From a8015bd96488cc7e239521b6f48a0938ccda7264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 27 Jun 2025 09:58:03 +0200 Subject: [PATCH 001/103] wip --- .../blocks/rules/kibana/BaseKibanaRule.scala | 1 - .../rules/kibana/KibanaAccessRule.scala | 2 +- .../ror/accesscontrol/domain/indices.scala | 9 +- .../kibana/KibanaUserDataRuleDecoder.scala | 4 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 46 +++--- .../beshu/ror/configuration/EsConfig.scala | 137 +++++++++++------- .../ror/configuration/FipsConfiguration.scala | 2 +- .../RorIndexNameConfiguration.scala | 57 -------- .../ror/configuration/SslConfiguration.scala | 2 +- .../YamlFileBasedConfigLoader.scala | 1 - .../RawRorConfigLoadingAction.scala | 11 +- ...esolvingYamlLoadedAccessControlTests.scala | 2 +- .../kibana/KibanaUserDataRuleTests.scala | 18 +-- .../rrconfig/TransportRRConfigAction.scala | 16 +- gradle.properties | 2 +- 15 files changed, 151 insertions(+), 159 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/RorIndexNameConfiguration.scala diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala index 89cc6d44e7..9a424697d6 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala @@ -23,7 +23,6 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.rules.Rule.RegularRule import tech.beshu.ror.accesscontrol.blocks.rules.kibana.BaseKibanaRule.* import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaActionMatchers.* -import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Local.devNullKibana import tech.beshu.ror.accesscontrol.domain.KibanaAccess.* import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.KibanaIndexName.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala index 4a1d9cdc6d..d0e695a1eb 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala @@ -49,7 +49,7 @@ class KibanaAccessRule(override val settings: Settings) } private def kibanaIndexFrom(blockContext: BlockContext): KibanaIndexName = { - blockContext.userMetadata.kibanaIndex.getOrElse(ClusterIndexName.Local.kibanaDefault) + blockContext.userMetadata.kibanaIndex.getOrElse(KibanaIndexName.default) } } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala index 1382410f7d..9f4f0eb2a4 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala @@ -22,6 +22,7 @@ import cats.implicits.* import com.github.benmanes.caffeine.cache.{Cache, Caffeine} import eu.timepit.refined.auto.* import eu.timepit.refined.types.string.NonEmptyString +import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Local import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Remote.ClusterName import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher.Matchable @@ -74,6 +75,9 @@ object IndexName { final case class KibanaIndexName(underlying: ClusterIndexName.Local) object KibanaIndexName { + val devNullKibana: KibanaIndexName = KibanaIndexName(Local(IndexName.Full(nes(".kibana-devnull")))) + val default: KibanaIndexName = KibanaIndexName(Local(IndexName.Full(nes(".kibana")))) + private val kibanaIndicesRegexesCache: Cache[KibanaIndexName, Vector[Regex]] = Caffeine.newBuilder() .executor(global) @@ -182,7 +186,7 @@ object ClusterIndexName { object Local { val wildcard: ClusterIndexName.Local = Local(IndexName.wildcard) - val devNullKibana: KibanaIndexName = KibanaIndexName(Local(IndexName.Full(nes(".kibana-devnull")))) + val kibanaDefault: KibanaIndexName = KibanaIndexName(Local(IndexName.Full(nes(".kibana")))) def fromString(value: String): Option[ClusterIndexName.Local] = { @@ -525,3 +529,6 @@ object IndexAttribute { final case class RorConfigurationIndex(index: IndexName.Full) extends AnyVal { def toLocal: ClusterIndexName.Local = ClusterIndexName.Local(index) } +object RorConfigurationIndex { + val default: RorConfigurationIndex = RorConfigurationIndex(IndexName.Full(nes(".readonlyrest"))) +} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala index d1970219b2..278aaf1af9 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala @@ -64,9 +64,7 @@ class KibanaUserDataRuleDecoder(configurationIndex: RorConfigurationIndex, } } yield new KibanaUserDataRule(KibanaUserDataRule.Settings( access = access, - kibanaIndex = kibanaIndex.getOrElse( - RuntimeSingleResolvableVariable.AlreadyResolved(ClusterIndexName.Local.kibanaDefault - )), + kibanaIndex = kibanaIndex.getOrElse(RuntimeSingleResolvableVariable.AlreadyResolved(KibanaIndexName.default)), kibanaTemplateIndex = kibanaTemplateIndex, appsToHide = appsToHide.getOrElse(Set.empty), allowedApiPaths = allowedApiPaths.getOrElse(Set.empty), diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index fa862bd297..9a71319287 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,6 +34,7 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.ConfigLoading.{ErrorOr, LoadRorConfig} +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.TestConfigLoading.* import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.* @@ -67,38 +68,43 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadRorConfig(esConfig: EsConfig) = { - val action = - if (esConfig.rorEsLevelSettings.forceLoadRorFromFile) { + val action = esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile => LoadRawRorConfig.loadFromFile(esEnv.configPath) - } else { + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(environmentConfig.propertiesProvider) val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(environmentConfig.propertiesProvider) val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(environmentConfig.propertiesProvider) LoadRawRorConfig .loadFromIndexWithFileFallback( - configurationIndex = esConfig.rorIndex.index, + configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, loadingDelay = loadingDelay, loadingAttemptsCount = loadingAttemptsCount, loadingAttemptsInterval = loadingAttemptsInterval, fallbackConfigFilePath = esEnv.configPath ) - } + } runStartingFailureProgram(action) } private def loadRorTestConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { - val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(environmentConfig.propertiesProvider) - val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(environmentConfig.propertiesProvider) - val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(environmentConfig.propertiesProvider) - val action = LoadRawTestRorConfig - .loadFromIndexWithFallback( - configurationIndex = esConfig.rorIndex.index, - loadingDelay = loadingDelay, - indexLoadingAttemptsCount = loadingAttemptsCount, - indexLoadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfig = notSetTestRorConfig - ) - EitherT.right(runTestProgram(action)) + esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile => + EitherT.right(Task.now(LoadedTestRorConfig.FallbackConfig(TestRorConfig.NotSet))) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => + val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(environmentConfig.propertiesProvider) + val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(environmentConfig.propertiesProvider) + val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(environmentConfig.propertiesProvider) + val action = LoadRawTestRorConfig + .loadFromIndexWithFallback( + configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, + loadingDelay = loadingDelay, + indexLoadingAttemptsCount = loadingAttemptsCount, + indexLoadingAttemptsInterval = loadingAttemptsInterval, + fallbackConfig = notSetTestRorConfig + ) + EitherT.right(runTestProgram(action)) + } } private def runStartingFailureProgram[A](action: LoadRorConfig[ErrorOr[A]]) = { @@ -149,9 +155,9 @@ class ReadonlyRest(coreFactory: CoreFactory, loadedConfig: LoadedRorConfig[RawRorConfig], loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { for { - mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorIndex.index)) + mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorEsLevelSettings.rorConfigIndex)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) - rorInstance <- createRorInstance(esConfig.rorIndex.index, mainEngine, testEngine, loadedConfig) + rorInstance <- createRorInstance(esConfig.rorEsLevelSettings.rorConfigIndex, mainEngine, testEngine, loadedConfig) } yield rorInstance } @@ -169,7 +175,7 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadActiveTestEngine(esConfig: EsConfig, testConfig: TestRorConfig.Present) = { for { _ <- Task.delay(authServicesMocksProvider.update(testConfig.mocks)) - testEngine <- loadRorCore(testConfig.rawConfig, esConfig.rorIndex.index) + testEngine <- loadRorCore(testConfig.rawConfig, esConfig.rorEsLevelSettings.rorConfigIndex) .map { case Right(loadedEngine) => TestEngine.Configured( diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala index 6ff32ca7a4..feca8731f6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala @@ -18,21 +18,23 @@ package tech.beshu.ror.configuration import better.files.File import cats.data.{EitherT, NonEmptyList} +import eu.timepit.refined.types.string.NonEmptyString import io.circe.Decoder import monix.eval.Task +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.FipsConfiguration.FipsMode import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.language.implicitConversions -final case class EsConfig(rorEsLevelSettings: RorEsLevelSettings, - ssl: RorSsl, - rorIndex: RorIndexNameConfiguration, - fipsConfiguration: FipsConfiguration) +final case class EsConfig(rorEsLevelSettings: RorEsLevelSettings) object EsConfig { @@ -41,28 +43,29 @@ object EsConfig { val configFile = esEnv.elasticsearchConfig (for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) - esSettings <- parse(configFile, esEnv.isOssDistribution) - ssl <- loadSslSettings(esEnv, esSettings.xpackSettings) - rorIndex <- loadRorIndexNameConfiguration(configFile) - fipsConfiguration <- loadFipsConfiguration(esEnv, esSettings.xpackSettings) - } yield EsConfig(esSettings.rorSettings, ssl, rorIndex, fipsConfiguration)).value + rorEsLevelSettings <- loadRorEsLevelSettings(esEnv) + } yield EsConfig(rorEsLevelSettings)).value } - private def parse(configFile: File, ossDistribution: Boolean) - (implicit environmentConfig: EnvironmentConfig): EitherT[Task, LoadEsConfigError, EsSettings] = { - implicit val decoder: Decoder[EsSettings] = decoders.esSettingsDecoder(ossDistribution) - EitherT.fromEither[Task]( - environmentConfig - .yamlParser - .parse(configFile) - .left.map(_.message) - .flatMap { json => - decoder - .decodeJson(json) - .left.map(_.message) - } - .left.map(MalformedContent(configFile, _)) - ) + private def loadRorEsLevelSettings(esEnv: EsEnv) + (implicit environmentConfig: EnvironmentConfig) = { + for { + loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) + (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex + xpackSettings <- loadXpackSettings(esEnv, esEnv.isOssDistribution) + sslSettings <- loadSslSettings(esEnv, xpackSettings) + fibsConfiguration <- loadFipsConfiguration(esEnv, xpackSettings) + } yield RorEsLevelSettings(rorIndex, loadingRorCoreStrategy, sslSettings, fibsConfiguration) + } + + private def loadXpackSettings(esEnv: EsEnv, ossDistribution: Boolean) + (implicit environmentConfig: EnvironmentConfig) = { + EitherT.fromEither[Task] { + implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) + new YamlFileBasedConfigLoader(esEnv.configPath) + .loadConfig[XpackSettings](configName = "X-Pack settings") + .left.map(error => MalformedContent(esEnv.configPath, error.message)) + } } private def loadSslSettings(esEnv: EsEnv, xpackSettings: XpackSettings) @@ -70,7 +73,7 @@ object EsConfig { EitherT(RorSsl.load(esEnv)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) .subflatMap { rorSsl => - if(rorSsl != RorSsl.noSsl && xpackSettings.securityEnabled) { + if (rorSsl != RorSsl.noSsl && xpackSettings.securityEnabled) { Left(RorSettingsInactiveWhenXpackSecurityIsEnabled(SettingsType.Ssl)) } else { Right(rorSsl) @@ -78,11 +81,6 @@ object EsConfig { } } - private def loadRorIndexNameConfiguration(configFile: File) - (implicit environmentConfig: EnvironmentConfig): EitherT[Task, LoadEsConfigError, RorIndexNameConfiguration] = { - EitherT(RorIndexNameConfiguration.load(configFile).map(_.left.map(error => MalformedContent(configFile, error.message)))) - } - private def loadFipsConfiguration(esEnv: EsEnv, xpackSettings: XpackSettings) (implicit environmentConfig: EnvironmentConfig): EitherT[Task, LoadEsConfigError, FipsConfiguration] = { EitherT(FipsConfiguration.load(esEnv)) @@ -97,10 +95,34 @@ object EsConfig { } } - final case class EsSettings(rorSettings: RorEsLevelSettings, - xpackSettings: XpackSettings) - final case class RorEsLevelSettings(forceLoadRorFromFile: Boolean) - final case class XpackSettings(securityEnabled: Boolean) + private def loadLoadingRorCoreStrategyAndRorIndex(esEnv: EsEnv) + (implicit environmentConfig: EnvironmentConfig) = { + EitherT.fromEither[Task] { + import decoders.{loadRorCoreStrategyDecoder, rorConfigurationIndexDecoder} + val loader = new YamlFileBasedConfigLoader(esEnv.configPath) + for { + strategy <- loader + .loadConfig[LoadingRorCoreStrategy](configName = "ROR loading core settings") + .left.map(error => MalformedContent(esEnv.configPath, error.message)) + rorIndex <- loader + .loadConfig[RorConfigurationIndex](configName = "ROR configuration index settings") + .left.map(error => MalformedContent(esEnv.configPath, error.message)) + } yield (strategy, rorIndex) + } + } + + final case class RorEsLevelSettings(rorConfigIndex: RorConfigurationIndex, + loadingRorCoreStrategy: LoadingRorCoreStrategy, + ssl: RorSsl, + fipsConfiguration: FipsConfiguration) + object RorEsLevelSettings { + sealed trait LoadingRorCoreStrategy + object LoadingRorCoreStrategy { + case object ForceLoadingFromFile extends LoadingRorCoreStrategy + case object LoadFromIndexWithFileFallback extends LoadingRorCoreStrategy + } + } + private final case class XpackSettings(securityEnabled: Boolean) sealed trait LoadEsConfigError object LoadEsConfigError { @@ -117,32 +139,43 @@ object EsConfig { } private object decoders { - implicit val rorEsLevelSettingsDecoder: Decoder[RorEsLevelSettings] = { + implicit val loadRorCoreStrategyDecoder: Decoder[LoadingRorCoreStrategy] = { YamlKeyDecoder[Boolean]( segments = NonEmptyList.of("readonlyrest", "force_load_from_file"), default = false - ) map RorEsLevelSettings.apply + ) map { + case true => ForceLoadingFromFile + case false => LoadFromIndexWithFileFallback + } } - implicit val xpackSettingsDecoder: Decoder[XpackSettings] = { - val booleanDecoder = YamlKeyDecoder[Boolean]( - segments = NonEmptyList.of("xpack", "security", "enabled"), - default = true + implicit val rorConfigurationIndexDecoder: Decoder[RorConfigurationIndex] = { + implicit val indexNameDecoder: Decoder[RorConfigurationIndex] = + Decoder[NonEmptyString] + .map(IndexName.Full.apply) + .map(RorConfigurationIndex.apply) + YamlKeyDecoder[RorConfigurationIndex]( + segments = NonEmptyList.of("readonlyrest", "settings_index"), + default = RorConfigurationIndex.default ) - val stringDecoder = YamlKeyDecoder[String]( - segments = NonEmptyList.of("xpack", "security", "enabled"), - default = "true" - ) map { _.toBoolean } - (booleanDecoder or stringDecoder) map XpackSettings.apply } - implicit def esSettingsDecoder(isOssDistribution: Boolean): Decoder[EsSettings] = { - for { - rorEsLevelSettings <- Decoder[RorEsLevelSettings] - xpackSettings <- - if(isOssDistribution) Decoder.const(XpackSettings(securityEnabled = false)) - else Decoder[XpackSettings] - } yield EsSettings(rorEsLevelSettings, xpackSettings) + def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSettings] = { + if (isOssDistribution) { + Decoder.const(XpackSettings(securityEnabled = false)) + } else { + val booleanDecoder = YamlKeyDecoder[Boolean]( + segments = NonEmptyList.of("xpack", "security", "enabled"), + default = true + ) + val stringDecoder = YamlKeyDecoder[String]( + segments = NonEmptyList.of("xpack", "security", "enabled"), + default = "true" + ) map { + _.toBoolean + } + (booleanDecoder or stringDecoder) map XpackSettings.apply + } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala index 3a80e85e59..bf3f04967f 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala @@ -61,7 +61,7 @@ object FipsConfiguration extends Logging { private def loadFipsConfigFromFile(configFile: File) (implicit environmentConfig: EnvironmentConfig): Either[MalformedSettings, FipsConfiguration] = { - new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Configuration") + new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Settings") } private implicit val fipsModeDecoder: Decoder[FipsMode] = { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorIndexNameConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorIndexNameConfiguration.scala deleted file mode 100644 index 6e5008612a..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorIndexNameConfiguration.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import better.files.File -import cats.data.NonEmptyList -import eu.timepit.refined.types.string.NonEmptyString -import io.circe.Decoder -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} -import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.* -import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.utils.RefinedUtils.* -import tech.beshu.ror.utils.yaml.YamlKeyDecoder - -final case class RorIndexNameConfiguration(index: RorConfigurationIndex) - -object RorIndexNameConfiguration extends Logging { - - private val defaultIndexName = IndexName.Full(nes(".readonlyrest")) - - def load(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, RorIndexNameConfiguration]] = { - load(esEnv.elasticsearchConfig) - } - - def load(esConfig: File) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, RorIndexNameConfiguration]] = Task { - new YamlFileBasedConfigLoader(esConfig).loadConfig[RorIndexNameConfiguration](configName = "ROR index configuration") - } - - private implicit val rorIndexNameConfigurationDecoder: Decoder[RorIndexNameConfiguration] = { - implicit val indexNameDecoder: Decoder[IndexName.Full] = Decoder[NonEmptyString].map(IndexName.Full.apply) - - YamlKeyDecoder[IndexName.Full]( - segments = NonEmptyList.of("readonlyrest", "settings_index"), - default = defaultIndexName - ) - .map(RorConfigurationIndex.apply) - .map(RorIndexNameConfiguration.apply) - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 9ab59c953c..5589f1493e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -69,7 +69,7 @@ object RorSsl extends Logging { private def loadSslConfigFromFile(configFile: File) (implicit rorSslDecoder: Decoder[RorSsl], environmentConfig: EnvironmentConfig) = { - new YamlFileBasedConfigLoader(configFile).loadConfig[RorSsl](configName = "ROR SSL configuration") + new YamlFileBasedConfigLoader(configFile).loadConfig[RorSsl](configName = "ROR SSL settings") } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala index ef4814ec02..cf80fb2ce4 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala @@ -21,7 +21,6 @@ import io.circe.{Decoder, DecodingFailure, Json} import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.factory.JsonConfigStaticVariableResolver import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.yaml import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson final class YamlFileBasedConfigLoader(file: File) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala index ddec11478a..f557c7be96 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala @@ -18,6 +18,8 @@ package tech.beshu.ror.configuration.loader.distributed import cats.data.EitherT import monix.eval.Task +import tech.beshu.ror.configuration.ConfigLoading.LoadRorConfig +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.IndexConfigManager import tech.beshu.ror.configuration.loader.{ConfigLoadingInterpreter, LoadRawRorConfig, LoadedRorConfig} import tech.beshu.ror.configuration.{ConfigLoading, EnvironmentConfig, RawRorConfig} @@ -30,7 +32,14 @@ object RawRorConfigLoadingAction { val compiler = ConfigLoadingInterpreter.create(new IndexConfigManager(indexJsonContentService)) (for { esConfig <- EitherT(ConfigLoading.loadEsConfig(env)) - loadedConfig <- EitherT(LoadRawRorConfig.loadFromIndex(esConfig.rorIndex.index)) + loadedConfig <- esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile => + EitherT.leftT[LoadRorConfig, LoadedRorConfig[RawRorConfig]]( + LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled("todo"): LoadedRorConfig.Error // todo: fixme + ) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => + EitherT(LoadRawRorConfig.loadFromIndex(esConfig.rorEsLevelSettings.rorConfigIndex)) + } } yield loadedConfig).value.foldMap(compiler) } diff --git a/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala index 2563191ce3..ffac563b0f 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala @@ -373,7 +373,7 @@ class VariableResolvingYamlLoadedAccessControlTests extends AnyWordSpec .from(request) .withLoggedUser(DirectlyLoggedUser(User.Id("user9"))) .withKibanaAccess(KibanaAccess.RO) - .withKibanaIndex(ClusterIndexName.Local.kibanaDefault) + .withKibanaIndex(KibanaIndexName.default) .withKibanaMetadata( JsonTree.Object(Map( "a" -> JsonTree.Value(JsonValue.StringValue("jwt_value_j0,j3")), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala index bc2b40c955..e88d5de7b5 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala @@ -53,7 +53,7 @@ class KibanaUserDataRuleTests val kibanaTemplateIndex = kibanaIndexName("kibana_template_index") val rule = createRuleFrom(KibanaUserDataRule.Settings( access = KibanaAccess.Unrestricted, - kibanaIndex = AlreadyResolved(ClusterIndexName.Local.kibanaDefault), + kibanaIndex = AlreadyResolved(KibanaIndexName.default), kibanaTemplateIndex = Some(AlreadyResolved(kibanaTemplateIndex)), appsToHide = Set.empty, allowedApiPaths = Set.empty, @@ -67,7 +67,7 @@ class KibanaUserDataRuleTests .withLoggedUser(LoggedUser.DirectlyLoggedUser(User.Id("user1"))) .withCurrentGroupId(GroupId("mygroup")) .withKibanaAccess(KibanaAccess.Unrestricted) - .withKibanaIndex(ClusterIndexName.Local.kibanaDefault) + .withKibanaIndex(KibanaIndexName.default) .withKibanaTemplateIndex(kibanaTemplateIndex) } } @@ -77,7 +77,7 @@ class KibanaUserDataRuleTests val apps: UniqueNonEmptyList[KibanaApp] = UniqueNonEmptyList.of(FullNameKibanaApp("app1"), FullNameKibanaApp("app2")) val rule = createRuleFrom(KibanaUserDataRule.Settings( access = KibanaAccess.Unrestricted, - kibanaIndex = AlreadyResolved(ClusterIndexName.Local.kibanaDefault), + kibanaIndex = AlreadyResolved(KibanaIndexName.default), kibanaTemplateIndex = None, appsToHide = apps.toCovariantSet, allowedApiPaths = Set.empty, @@ -91,7 +91,7 @@ class KibanaUserDataRuleTests .withLoggedUser(LoggedUser.DirectlyLoggedUser(User.Id("user1"))) .withCurrentGroupId(GroupId("mygroup")) .withKibanaAccess(KibanaAccess.Unrestricted) - .withKibanaIndex(ClusterIndexName.Local.kibanaDefault) + .withKibanaIndex(KibanaIndexName.default) .withHiddenKibanaApps(apps) } } @@ -114,7 +114,7 @@ class KibanaUserDataRuleTests ) val rule = createRuleFrom(KibanaUserDataRule.Settings( access = KibanaAccess.Unrestricted, - kibanaIndex = AlreadyResolved(ClusterIndexName.Local.kibanaDefault), + kibanaIndex = AlreadyResolved(KibanaIndexName.default), kibanaTemplateIndex = None, appsToHide = Set.empty, allowedApiPaths = paths.toCovariantSet, @@ -128,7 +128,7 @@ class KibanaUserDataRuleTests .withLoggedUser(LoggedUser.DirectlyLoggedUser(User.Id("user1"))) .withCurrentGroupId(GroupId("mygroup")) .withKibanaAccess(KibanaAccess.Unrestricted) - .withKibanaIndex(ClusterIndexName.Local.kibanaDefault) + .withKibanaIndex(KibanaIndexName.default) .withAllowedKibanaApiPaths(paths) } } @@ -156,7 +156,7 @@ class KibanaUserDataRuleTests } val rule = createRuleFrom(KibanaUserDataRule.Settings( access = KibanaAccess.Unrestricted, - kibanaIndex = AlreadyResolved(ClusterIndexName.Local.kibanaDefault), + kibanaIndex = AlreadyResolved(KibanaIndexName.default), kibanaTemplateIndex = None, appsToHide = Set.empty, allowedApiPaths = Set.empty, @@ -170,7 +170,7 @@ class KibanaUserDataRuleTests .withLoggedUser(LoggedUser.DirectlyLoggedUser(User.Id("user1"))) .withCurrentGroupId(GroupId("mygroup")) .withKibanaAccess(KibanaAccess.Unrestricted) - .withKibanaIndex(ClusterIndexName.Local.kibanaDefault) + .withKibanaIndex(KibanaIndexName.default) .withKibanaMetadata( JsonTree.Object(Map( "a" -> JsonTree.Value(NumValue(1)), @@ -221,7 +221,7 @@ class KibanaUserDataRuleTests customKibanaIndex: Option[KibanaIndexName] = None): KibanaUserDataRule.Settings = KibanaUserDataRule.Settings( access = access, - kibanaIndex = AlreadyResolved(customKibanaIndex.getOrElse(ClusterIndexName.Local.kibanaDefault)), + kibanaIndex = AlreadyResolved(customKibanaIndex.getOrElse(KibanaIndexName.default)), kibanaTemplateIndex = None, appsToHide = Set.empty, allowedApiPaths = Set.empty, diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index c0aba7ad0b..9d4371d974 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -96,20 +96,18 @@ class TransportRRConfigAction(actionName: String, override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) + val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) } + private def loadConfig() = doPrivileged { + RawRorConfigLoadingAction + .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) + .map(_.map(_.map(_.raw))) + } + private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos } diff --git a/gradle.properties b/gradle.properties index 72a8347a08..6c14579926 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ publishedPluginVersion=1.64.2 -pluginVersion=1.65.0-pre7 +pluginVersion=1.65.0-pre8 pluginName=readonlyrest org.gradle.jvmargs=-Xmx6144m From 9edfe40884eff50e34a64d1a5ec7ff9641ea01d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 27 Jun 2025 15:47:35 +0200 Subject: [PATCH 002/103] wip --- .../decoders/AuditingSettingsDecoder.scala | 2 +- .../beshu/ror/configuration/EsConfig.scala | 10 +++++---- .../configuration/RorBootConfiguration.scala | 4 ++-- .../beshu/ror/utils/yaml/YamlKeyDecoder.scala | 22 +++++++++++++------ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala index c346a8244c..83627f4580 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala @@ -52,7 +52,7 @@ object AuditingSettingsDecoder extends Logging { private def auditSettingsDecoder(esVersion: EsVersion): Decoder[Option[AuditingTool.Settings]] = Decoder.instance { c => for { isAuditEnabled <- YamlKeyDecoder[Boolean]( - segments = NonEmptyList.of("audit", "enabled"), + path = NonEmptyList.of("audit", "enabled"), default = false ).apply(c) result <- if (isAuditEnabled) { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala index feca8731f6..6e1bee4acd 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala @@ -141,7 +141,8 @@ object EsConfig { private object decoders { implicit val loadRorCoreStrategyDecoder: Decoder[LoadingRorCoreStrategy] = { YamlKeyDecoder[Boolean]( - segments = NonEmptyList.of("readonlyrest", "force_load_from_file"), + path = NonEmptyList.of("readonlyrest", "settings", "file", "force_load_from_file"), + alternativePath = NonEmptyList.of("readonlyrest", "force_load_from_file"), // for a sake of backward compatibility default = false ) map { case true => ForceLoadingFromFile @@ -155,7 +156,8 @@ object EsConfig { .map(IndexName.Full.apply) .map(RorConfigurationIndex.apply) YamlKeyDecoder[RorConfigurationIndex]( - segments = NonEmptyList.of("readonlyrest", "settings_index"), + path = NonEmptyList.of("readonlyrest", "settings", "in_index", "index_name"), + alternativePath = NonEmptyList.of("readonlyrest", "settings_index"), // for a sake of backward compatibility default = RorConfigurationIndex.default ) } @@ -165,11 +167,11 @@ object EsConfig { Decoder.const(XpackSettings(securityEnabled = false)) } else { val booleanDecoder = YamlKeyDecoder[Boolean]( - segments = NonEmptyList.of("xpack", "security", "enabled"), + path = NonEmptyList.of("xpack", "security", "enabled"), default = true ) val stringDecoder = YamlKeyDecoder[String]( - segments = NonEmptyList.of("xpack", "security", "enabled"), + path = NonEmptyList.of("xpack", "security", "enabled"), default = "true" ) map { _.toBoolean diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala index eefe0b15e1..a201517ff2 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala @@ -89,7 +89,7 @@ private object Decoders extends Logging { } YamlKeyDecoder[RorNotStartedResponse.HttpCode]( - segments = segments, + path = segments, default = RorNotStartedResponse.HttpCode.`403` ) .map(RorNotStartedResponse.apply) @@ -107,7 +107,7 @@ private object Decoders extends Logging { } YamlKeyDecoder[RorFailedToStartResponse.HttpCode]( - segments = segments, + path = segments, default = RorFailedToStartResponse.HttpCode.`403` ) .map(RorFailedToStartResponse.apply) diff --git a/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala index b12c503c4a..0cc07b6b6f 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala @@ -20,15 +20,13 @@ import cats.data.NonEmptyList import io.circe.Decoder.Result import io.circe.{ACursor, Decoder, HCursor} -private class YamlKeyDecoder[A: Decoder](segments: NonEmptyList[String], default: A) extends Decoder[A] { - override def apply(c: HCursor): Result[A] = { +private class YamlKeyDecoder[A: Decoder](segments: NonEmptyList[String]) extends Decoder[Option[A]] { + override def apply(c: HCursor): Result[Option[A]] = { for { oneLine <- downOneLineField(c).as[Option[A]] multiLine <- downMultiLineField(c).as[Option[A]] } yield { - oneLine - .orElse(multiLine) - .getOrElse(default) + oneLine.orElse(multiLine) } } @@ -44,7 +42,17 @@ private class YamlKeyDecoder[A: Decoder](segments: NonEmptyList[String], default } object YamlKeyDecoder { - def apply[A: Decoder](segments: NonEmptyList[String], default: A): Decoder[A] = { - new YamlKeyDecoder[A](segments, default) + def apply[A: Decoder](path: NonEmptyList[String], default: A): Decoder[A] = { + new YamlKeyDecoder[A](path).map(_.getOrElse(default)) + } + + def apply[A: Decoder](path: NonEmptyList[String], alternativePath: NonEmptyList[String], default: A): Decoder[A] = { + for { + decodedValue <- new YamlKeyDecoder[A](path) + alternativeDecodedValue <- decodedValue match { + case Some(value) => Decoder.const[Option[A]](Some(value)) + case None => new YamlKeyDecoder[A](alternativePath) + } + } yield alternativeDecodedValue.getOrElse(default) } } \ No newline at end of file From bd2d730ab01597f815e6fea36faf86efed1266dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 30 Jun 2025 14:37:59 +0200 Subject: [PATCH 003/103] refactoring --- ...onmentConfig.scala => SystemContext.scala} | 21 ++++++------ .../RawRorConfigBasedCoreFactory.scala | 15 ++++---- .../factory/decoders/ruleDecoders.scala | 14 ++++---- .../scala/tech/beshu/ror/api/ConfigApi.scala | 5 +-- .../tech/beshu/ror/api/TestConfigApi.scala | 5 +-- .../tech/beshu/ror/boot/ReadonlyRest.scala | 31 +++++++++-------- .../tech/beshu/ror/boot/RorInstance.scala | 17 +++++----- .../boot/engines/BaseReloadableEngine.scala | 13 +++---- .../MainConfigBasedReloadableEngine.scala | 5 +-- .../TestConfigBasedReloadableEngine.scala | 7 ++-- .../beshu/ror/configuration/EsConfig.scala | 34 +++++++++++++------ .../ror/configuration/FipsConfiguration.scala | 9 ++--- .../ror/configuration/RawRorConfig.scala | 7 ++-- .../configuration/ReadonlyRestEsConfig.scala | 3 +- .../configuration/RorBootConfiguration.scala | 5 +-- .../ror/configuration/SslConfiguration.scala | 9 ++--- .../YamlFileBasedConfigLoader.scala | 9 ++--- .../index/IndexConfigManager.scala | 5 +-- .../index/IndexTestConfigManager.scala | 5 +-- .../loader/ConfigLoadingInterpreter.scala | 9 ++--- .../loader/FileConfigLoader.scala | 21 ++++-------- .../RawRorConfigLoadingAction.scala | 9 ++--- .../BaseYamlLoadedAccessControlTest.scala | 4 +-- .../unit/acl/factory/AuditSettingsTests.scala | 4 +-- .../unit/acl/factory/CoreFactoryTests.scala | 4 +-- .../factory/ImpersonationWarningsTests.scala | 4 +-- .../ror/unit/acl/factory/LocalUsersTest.scala | 4 +-- .../rules/BaseRuleSettingsDecoderTest.scala | 4 +-- .../unit/boot/ReadonlyRestStartingTests.scala | 4 +-- .../beshu/ror/unit/boot/RorIndexTest.scala | 4 +-- .../RorBootConfigurationTest.scala | 4 +-- .../configuration/SslConfigurationTest.scala | 4 +-- .../YamlFileBasedConfigLoaderTest.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 9 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 8 ++--- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 ++-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 8 ++--- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +-- .../rrconfig/TransportRRConfigAction.scala | 4 +-- 126 files changed, 408 insertions(+), 381 deletions(-) rename core/src/main/scala/tech/beshu/ror/{configuration/EnvironmentConfig.scala => SystemContext.scala} (60%) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EnvironmentConfig.scala b/core/src/main/scala/tech/beshu/ror/SystemContext.scala similarity index 60% rename from core/src/main/scala/tech/beshu/ror/configuration/EnvironmentConfig.scala rename to core/src/main/scala/tech/beshu/ror/SystemContext.scala index 2adb0da79a..a85ed97c54 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EnvironmentConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/SystemContext.scala @@ -14,28 +14,29 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror import tech.beshu.ror.accesscontrol.blocks.variables.transformation.SupportedVariablesFunctions import tech.beshu.ror.accesscontrol.matchers.{RandomBasedUniqueIdentifierGenerator, UniqueIdentifierGenerator} +import tech.beshu.ror.configuration.RorProperties import tech.beshu.ror.providers.* import tech.beshu.ror.utils.js.{JsCompiler, MozillaJsCompiler} import tech.beshu.ror.utils.yaml.RorYamlParser import java.time.Clock -final class EnvironmentConfig(val clock: Clock = Clock.systemUTC(), - val envVarsProvider: EnvVarsProvider = OsEnvVarsProvider, - val propertiesProvider: PropertiesProvider = JvmPropertiesProvider, - val uniqueIdentifierGenerator: UniqueIdentifierGenerator = RandomBasedUniqueIdentifierGenerator, - val uuidProvider: UuidProvider = JavaUuidProvider, - val jsCompiler: JsCompiler = MozillaJsCompiler, - val variablesFunctions: SupportedVariablesFunctions = SupportedVariablesFunctions.default) { +final class SystemContext(val clock: Clock = Clock.systemUTC(), + val envVarsProvider: EnvVarsProvider = OsEnvVarsProvider, + val propertiesProvider: PropertiesProvider = JvmPropertiesProvider, + val uniqueIdentifierGenerator: UniqueIdentifierGenerator = RandomBasedUniqueIdentifierGenerator, + val uuidProvider: UuidProvider = JavaUuidProvider, + val jsCompiler: JsCompiler = MozillaJsCompiler, + val variablesFunctions: SupportedVariablesFunctions = SupportedVariablesFunctions.default) { val yamlParser: RorYamlParser = new RorYamlParser(RorProperties.rorSettingsMaxSize(propertiesProvider)) } -object EnvironmentConfig { +object SystemContext { - val default: EnvironmentConfig = new EnvironmentConfig() + val default: SystemContext = new SystemContext() } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala index 98b63fc471..f79ea9c631 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala @@ -21,6 +21,7 @@ import cats.kernel.Monoid import io.circe.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.* import tech.beshu.ror.accesscontrol.EnabledAccessControlList.AccessControlListStaticContext import tech.beshu.ror.accesscontrol.audit.LoggingContext @@ -49,7 +50,7 @@ import tech.beshu.ror.accesscontrol.utils.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.FieldListResult.{FieldListValue, NoField} import tech.beshu.ror.configuration.RorConfig.ImpersonationWarningsReader -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} import tech.beshu.ror.es.EsVersion import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* @@ -68,7 +69,7 @@ trait CoreFactory { } class RawRorConfigBasedCoreFactory(esVersion: EsVersion) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends CoreFactory with Logging { override def createCoreFrom(config: RawRorConfig, @@ -101,8 +102,8 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { val jsonConfigResolver = new JsonConfigStaticVariableResolver( - environmentConfig.envVarsProvider, - TransformationCompiler.withoutAliases(environmentConfig.variablesFunctions), + systemContext.envVarsProvider, + TransformationCompiler.withoutAliases(systemContext.variablesFunctions), ) jsonConfigResolver.resolve(rorSection) match { case Right(resolvedRorSection) => @@ -310,10 +311,10 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) AsyncDecoderCreator.instance[Core] { c => val decoder = for { dynamicVariableTransformationAliases <- - AsyncDecoderCreator.from(VariableTransformationAliasesDefinitionsDecoder.create(environmentConfig.variablesFunctions)) + AsyncDecoderCreator.from(VariableTransformationAliasesDefinitionsDecoder.create(systemContext.variablesFunctions)) variableCreator = new RuntimeResolvableVariableCreator( TransformationCompiler.withAliases( - environmentConfig.variablesFunctions, + systemContext.variablesFunctions, dynamicVariableTransformationAliases.items.map(_.alias) ) ) @@ -322,7 +323,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) authenticationServices <- AsyncDecoderCreator.from(ExternalAuthenticationServicesDecoder.instance(httpClientFactory)) authorizationServices <- AsyncDecoderCreator.from(ExternalAuthorizationServicesDecoder.instance(httpClientFactory)) jwtDefs <- AsyncDecoderCreator.from(JwtDefinitionsDecoder.instance(httpClientFactory, variableCreator)) - ldapServices <- LdapServicesDecoder.ldapServicesDefinitionsDecoder(using ldapConnectionPoolProvider, environmentConfig.clock) + ldapServices <- LdapServicesDecoder.ldapServicesDefinitionsDecoder(using ldapConnectionPoolProvider, systemContext.clock) rorKbnDefs <- AsyncDecoderCreator.from(RorKbnDefinitionsDecoder.instance(variableCreator)) impersonationDefinitionsDecoderCreator = new ImpersonationDefinitionsDecoderCreator( globalSettings, authenticationServices, authProxies, ldapServices, mocksProvider diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala index 26b4b6a2da..8828a7a5b2 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala @@ -44,7 +44,7 @@ import tech.beshu.ror.accesscontrol.factory.decoders.rules.http.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.kibana.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.transport.* import tech.beshu.ror.accesscontrol.matchers.GenericPatternMatcher -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.implicits.* object ruleDecoders { @@ -53,10 +53,10 @@ object ruleDecoders { definitions: DefinitionsPack, globalSettings: GlobalSettings, mocksProvider: MocksProvider) - (implicit environmentConfig: EnvironmentConfig): Option[RuleDecoder[Rule]] = { + (implicit systemContext: SystemContext): Option[RuleDecoder[Rule]] = { val variableCreator = new RuntimeResolvableVariableCreator( TransformationCompiler.withAliases( - environmentConfig.variablesFunctions, + systemContext.variablesFunctions, definitions.variableTransformationAliases.items.map(_.alias) ) ) @@ -87,17 +87,17 @@ object ruleDecoders { case HeadersAndRule.DeprecatedName.name => Some(new HeadersAndRuleDecoder()(HeadersAndRule.DeprecatedName)) case HeadersOrRule.Name.name => Some(HeadersOrRuleDecoder) case HostsRule.Name.name => Some(new HostsRuleDecoder(variableCreator)) - case IndicesRule.Name.name => Some(new IndicesRuleDecoders(variableCreator, environmentConfig.uniqueIdentifierGenerator)) - case KibanaUserDataRule.Name.name => Some(new KibanaUserDataRuleDecoder(globalSettings.configurationIndex, variableCreator)(environmentConfig.jsCompiler)) + case IndicesRule.Name.name => Some(new IndicesRuleDecoders(variableCreator, systemContext.uniqueIdentifierGenerator)) + case KibanaUserDataRule.Name.name => Some(new KibanaUserDataRuleDecoder(globalSettings.configurationIndex, variableCreator)(systemContext.jsCompiler)) case KibanaAccessRule.Name.name => Some(new KibanaAccessRuleDecoder(globalSettings.configurationIndex)) - case KibanaHideAppsRule.Name.name => Some(new KibanaHideAppsRuleDecoder()(environmentConfig.jsCompiler)) + case KibanaHideAppsRule.Name.name => Some(new KibanaHideAppsRuleDecoder()(systemContext.jsCompiler)) case KibanaIndexRule.Name.name => Some(new KibanaIndexRuleDecoder(variableCreator)) case KibanaTemplateIndexRule.Name.name => Some(new KibanaTemplateIndexRuleDecoder(variableCreator)) case LocalHostsRule.Name.name => Some(new LocalHostsRuleDecoder(variableCreator)) case MaxBodyLengthRule.Name.name => Some(MaxBodyLengthRuleDecoder) case MethodsRule.Name.name => Some(MethodsRuleDecoder) case RepositoriesRule.Name.name => Some(new RepositoriesRuleDecoder(variableCreator)) - case SessionMaxIdleRule.Name.name => Some(new SessionMaxIdleRuleDecoder(globalSettings)(environmentConfig.clock, environmentConfig.uuidProvider)) + case SessionMaxIdleRule.Name.name => Some(new SessionMaxIdleRuleDecoder(globalSettings)(systemContext.clock, systemContext.uuidProvider)) case SnapshotsRule.Name.name => Some(new SnapshotsRuleDecoder(variableCreator)) case UriRegexRule.Name.name => Some(new UriRegexRuleDecoder(variableCreator)) case UsersRule.Name.name => Some(new UsersRuleDecoder(globalSettings, variableCreator)) diff --git a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala index 22b9f2c9dc..5484b1c126 100644 --- a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala @@ -22,6 +22,7 @@ import cats.implicits.* import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.api.ConfigApi.* import tech.beshu.ror.api.ConfigApi.ConfigRequest.Type @@ -29,7 +30,7 @@ import tech.beshu.ror.api.ConfigApi.ConfigResponse.* import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigReloadError, RawConfigReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.index.IndexConfigError.IndexConfigNotExist import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.SpecializedError @@ -40,7 +41,7 @@ class ConfigApi(rorInstance: RorInstance, indexConfigManager: IndexConfigManager, fileConfigLoader: FileConfigLoader, rorConfigurationIndex: RorConfigurationIndex) - (implicit val EnvironmentConfig: EnvironmentConfig) + (implicit val systemContext: SystemContext) extends Logging { import ConfigApi.Utils.* diff --git a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala index 2d72fb66c2..f548c9ea95 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala @@ -20,6 +20,7 @@ import cats.data.EitherT import cats.implicits.* import io.circe.Decoder import monix.eval.Task +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning import tech.beshu.ror.accesscontrol.domain.{LoggedUser, RequestId} import tech.beshu.ror.api.TestConfigApi.TestConfigRequest.Type @@ -28,7 +29,7 @@ import tech.beshu.ror.api.TestConfigApi.{TestConfigRequest, TestConfigResponse} import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, RawConfigReloadError, TestConfig} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* @@ -38,7 +39,7 @@ import scala.concurrent.duration.* import scala.util.Try class TestConfigApi(rorInstance: RorInstance) - (implicit environmentConfig: EnvironmentConfig) { + (implicit systemContext: SystemContext) { import tech.beshu.ror.api.TestConfigApi.Utils.* import tech.beshu.ror.api.TestConfigApi.Utils.decoders.* diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 9a71319287..dd1557f63a 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -20,6 +20,7 @@ import cats.data.{EitherT, NonEmptyList} import monix.eval.Task import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.audit.{AuditingTool, LoggingContext} import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider @@ -50,7 +51,7 @@ class ReadonlyRest(coreFactory: CoreFactory, val indexTestConfigManager: IndexTestConfigManager, val authServicesMocksProvider: MutableMocksProviderWithCachePerRequest, val esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { def start(): Task[Either[StartingFailure, RorInstance]] = { @@ -69,12 +70,12 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadRorConfig(esConfig: EsConfig) = { val action = esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile => + case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => LoadRawRorConfig.loadFromFile(esEnv.configPath) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => - val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(environmentConfig.propertiesProvider) - val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(environmentConfig.propertiesProvider) - val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(environmentConfig.propertiesProvider) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => + val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) + val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) + val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) LoadRawRorConfig .loadFromIndexWithFileFallback( configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, @@ -89,12 +90,12 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadRorTestConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile => + case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.right(Task.now(LoadedTestRorConfig.FallbackConfig(TestRorConfig.NotSet))) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => - val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(environmentConfig.propertiesProvider) - val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(environmentConfig.propertiesProvider) - val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(environmentConfig.propertiesProvider) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => + val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) + val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) + val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) val action = LoadRawTestRorConfig .loadFromIndexWithFallback( configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, @@ -165,7 +166,7 @@ class ReadonlyRest(coreFactory: CoreFactory, loadedTestRorConfig.value match { case TestRorConfig.NotSet => Task.now(TestEngine.NotConfigured) - case config: TestRorConfig.Present if !config.isExpired(environmentConfig.clock) => + case config: TestRorConfig.Present if !config.isExpired(systemContext.clock) => loadActiveTestEngine(esConfig, config) case config: TestRorConfig.Present => loadInvalidatedTestEngine(config) @@ -260,7 +261,7 @@ class ReadonlyRest(coreFactory: CoreFactory, private def createAuditingTool(core: Core) (implicit loggingContext: LoggingContext): Task[Either[NonEmptyList[CoreCreationError], Option[AuditingTool]]] = { core.rorConfig.auditingSettings - .map(settings => AuditingTool.create(settings, auditSinkServiceCreator)(using environmentConfig.clock, loggingContext)) + .map(settings => AuditingTool.create(settings, auditSinkServiceCreator)(using systemContext.clock, loggingContext)) .sequence .map { _.sequence @@ -334,7 +335,7 @@ object ReadonlyRest { auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) (implicit scheduler: Scheduler, - environmentConfig: EnvironmentConfig): ReadonlyRest = { + systemContext: SystemContext): ReadonlyRest = { val coreFactory: CoreFactory = new RawRorConfigBasedCoreFactory(env.esVersion) create(coreFactory, indexContentService, auditSinkServiceCreator, env) } @@ -344,7 +345,7 @@ object ReadonlyRest { auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) (implicit scheduler: Scheduler, - environmentConfig: EnvironmentConfig): ReadonlyRest = { + systemContext: SystemContext): ReadonlyRest = { val indexConfigManager: IndexConfigManager = new IndexConfigManager(indexContentService) val indexTestConfigManager: IndexTestConfigManager = new IndexTestConfigManager(indexContentService) val mocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 8a0ac8e9ec..1e8a4dcebf 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -24,6 +24,7 @@ import monix.catnap.Semaphore import monix.eval.Task import monix.execution.{Cancelable, Scheduler} import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} @@ -32,7 +33,7 @@ import tech.beshu.ror.configuration.RorProperties.RefreshInterval import tech.beshu.ror.configuration.index.{IndexConfigError, SavingIndexConfigError} import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.FileConfigLoader -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorConfig, RorProperties} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig, RorProperties} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -45,7 +46,7 @@ class RorInstance private(boot: ReadonlyRest, initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -55,7 +56,7 @@ class RorInstance private(boot: ReadonlyRest, logger.info("ReadonlyREST was loaded ...") private val configsReloadTask = mode match { case Mode.WithPeriodicIndexCheck => - RorProperties.rorIndexSettingsReloadInterval(environmentConfig.propertiesProvider) match { + RorProperties.rorIndexSettingsReloadInterval(systemContext.propertiesProvider) match { case RefreshInterval.Disabled => logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") Cancelable.empty @@ -83,7 +84,7 @@ class RorInstance private(boot: ReadonlyRest, private val configRestApi = new ConfigApi( rorInstance = this, boot.indexConfigManager, - new FileConfigLoader(boot.esEnv.configPath), + new FileConfigLoader(???), rorConfigurationIndex ) @@ -157,7 +158,7 @@ class RorInstance private(boot: ReadonlyRest, reloadTask: RequestId => Task[Seq[(ConfigType, Either[ScheduledReloadError, Unit])]]): Cancelable = { logger.debug(s"[CLUSTERWIDE SETTINGS] Scheduling next in-index settings check within ${interval.show}") scheduler.scheduleOnce(interval.value) { - implicit val requestId: RequestId = RequestId(environmentConfig.uuidProvider.random.toString) + implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST configs from index ...") reloadTask(requestId) .runAsync { @@ -271,7 +272,7 @@ object RorInstance { mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { create(boot, Mode.WithPeriodicIndexCheck, mainEngine, testEngine, rorConfigurationIndex) } @@ -280,7 +281,7 @@ object RorInstance { mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorConfigurationIndex) } @@ -290,7 +291,7 @@ object RorInstance { engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { isReloadInProgressSemaphore <- Semaphore[Task](1) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index ed8bb28961..9dd65e48fe 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -23,6 +23,7 @@ import monix.eval.Task import monix.execution.atomic.{Atomic, AtomicAny} import monix.execution.{Cancelable, Scheduler} import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.Engine @@ -30,7 +31,7 @@ import tech.beshu.ror.boot.RorInstance.RawConfigReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.* @@ -43,7 +44,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -53,7 +54,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, initialEngine match { case InitialEngine.Configured(engine, config, expirationConfig) => logger.info(s"ROR ${name.show} engine (id=${config.hashString().show}) was initiated (${engine.core.accessControl.description.show}).") - stateFromInitial(EngineWithConfig(engine, config, expirationConfig))(RequestId(environmentConfig.uuidProvider.random.toString)) + stateFromInitial(EngineWithConfig(engine, config, expirationConfig))(RequestId(systemContext.uuidProvider.random.toString)) case InitialEngine.NotConfigured => EngineState.NotStartedYet(recentConfig = None, recentExpirationConfig = None) case InitialEngine.Invalidated(config, expirationConfig) => @@ -88,7 +89,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, protected def invalidate(keepPreviousConfiguration: Boolean) (implicit requestId: RequestId): Task[Option[InvalidationResult]] = { Task.delay { - val invalidationTimestamp = environmentConfig.clock.instant() + val invalidationTimestamp = systemContext.clock.instant() val previous = currentEngine.getAndTransform { case notStarted: EngineState.NotStartedYet => if (keepPreviousConfiguration) { @@ -268,7 +269,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, private def engineExpirationConfig(configExpiration: UpdatedConfigExpiration) = { configExpiration match { case UpdatedConfigExpiration.ByTtl(ttl) => - EngineExpirationConfig(ttl = ttl, validTo = environmentConfig.clock.instant().plusMillis(ttl.value.toMillis)) + EngineExpirationConfig(ttl = ttl, validTo = systemContext.clock.instant().plusMillis(ttl.value.toMillis)) case UpdatedConfigExpiration.ToTime(validTo, configuredTtl) => EngineExpirationConfig(ttl = configuredTtl, validTo = validTo) } @@ -410,7 +411,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def isStillValid(validTo: Instant) = { - validTo.minusMillis(environmentConfig.clock.instant().toEpochMilli) + validTo.minusMillis(systemContext.clock.instant().toEpochMilli) .toEpochMilli.millis .toRefinedPositive .map(RemainingEngineTime.Valid.apply) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala index b4cdc9d2b9..c3ec1789a9 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala @@ -22,6 +22,7 @@ import cats.implicits.* import monix.catnap.Semaphore import monix.eval.Task import monix.execution.Scheduler +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.boot.ReadonlyRest @@ -31,7 +32,7 @@ import tech.beshu.ror.boot.RorInstance.RawConfigReloadError.{ConfigUpToDate, Rel import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.index.SavingIndexConfigError.CannotSaveConfig import tech.beshu.ror.utils.ScalaOps.value @@ -39,7 +40,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, initialEngine: (Engine, RawRorConfig), reloadInProgress: Semaphore[Task], rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine( name = "main", diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala index e545bb529c..d7fd925279 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala @@ -21,6 +21,7 @@ import cats.data.EitherT import monix.catnap.Semaphore import monix.eval.Task import monix.execution.Scheduler +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.implicits.* import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks @@ -33,7 +34,7 @@ import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpirationConfig, import tech.beshu.ror.boot.engines.ConfigHash.* import tech.beshu.ror.configuration.TestRorConfig.Present.ExpirationConfig import tech.beshu.ror.configuration.index.SavingIndexConfigError -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, TestRorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, TestRorConfig} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value @@ -41,7 +42,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine( "test", boot, initialEngine, reloadInProgress, rorConfigurationIndex @@ -237,7 +238,7 @@ object TestConfigBasedReloadableEngine { initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], rorConfigurationIndex: RorConfigurationIndex) - (implicit environmentConfig: EnvironmentConfig, + (implicit systemContext: SystemContext, scheduler: Scheduler): TestConfigBasedReloadableEngine = { val engine = initialEngine match { case TestEngine.NotConfigured => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala index 6e1bee4acd..171545cfdf 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala @@ -21,6 +21,8 @@ import cats.data.{EitherT, NonEmptyList} import eu.timepit.refined.types.string.NonEmptyString import io.circe.Decoder import monix.eval.Task +import squants.information.Information +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType @@ -29,6 +31,7 @@ import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.FipsConfiguration.FipsMode +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.yaml.YamlKeyDecoder @@ -39,7 +42,7 @@ final case class EsConfig(rorEsLevelSettings: RorEsLevelSettings) object EsConfig { def from(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[LoadEsConfigError, EsConfig]] = { + (implicit systemContext: SystemContext): Task[Either[LoadEsConfigError, EsConfig]] = { val configFile = esEnv.elasticsearchConfig (for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) @@ -48,7 +51,7 @@ object EsConfig { } private def loadRorEsLevelSettings(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig) = { + (implicit systemContext: SystemContext) = { for { loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex @@ -59,7 +62,7 @@ object EsConfig { } private def loadXpackSettings(esEnv: EsEnv, ossDistribution: Boolean) - (implicit environmentConfig: EnvironmentConfig) = { + (implicit systemContext: SystemContext) = { EitherT.fromEither[Task] { implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) new YamlFileBasedConfigLoader(esEnv.configPath) @@ -69,7 +72,7 @@ object EsConfig { } private def loadSslSettings(esEnv: EsEnv, xpackSettings: XpackSettings) - (implicit environmentConfig: EnvironmentConfig): EitherT[Task, LoadEsConfigError, RorSsl] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, RorSsl] = { EitherT(RorSsl.load(esEnv)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) .subflatMap { rorSsl => @@ -82,7 +85,7 @@ object EsConfig { } private def loadFipsConfiguration(esEnv: EsEnv, xpackSettings: XpackSettings) - (implicit environmentConfig: EnvironmentConfig): EitherT[Task, LoadEsConfigError, FipsConfiguration] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, FipsConfiguration] = { EitherT(FipsConfiguration.load(esEnv)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) .subflatMap { fipsConfiguration => @@ -96,7 +99,7 @@ object EsConfig { } private def loadLoadingRorCoreStrategyAndRorIndex(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig) = { + (implicit systemContext: SystemContext) = { EitherT.fromEither[Task] { import decoders.{loadRorCoreStrategyDecoder, rorConfigurationIndexDecoder} val loader = new YamlFileBasedConfigLoader(esEnv.configPath) @@ -118,9 +121,20 @@ object EsConfig { object RorEsLevelSettings { sealed trait LoadingRorCoreStrategy object LoadingRorCoreStrategy { - case object ForceLoadingFromFile extends LoadingRorCoreStrategy - case object LoadFromIndexWithFileFallback extends LoadingRorCoreStrategy + final case class ForceLoadingFromFile(settings: LoadFromFileSettings) extends LoadingRorCoreStrategy + final case class LoadFromIndexWithFileFallback(settings: LoadFromIndexSettings, + fallbackSettings: LoadFromFileSettings) + extends LoadingRorCoreStrategy } + + final case class LoadFromFileSettings(rorSettingsFile: File, + settingsMaxSize: Information) + final case class LoadFromIndexSettings(rorConfigIndex: RorConfigurationIndex, + refreshInterval: RefreshInterval, + loadingAttemptsInterval: LoadingAttemptsInterval, + loadingAttemptsCount: LoadingAttemptsCount, + loadingDelay: LoadingDelay, + settingsMaxSize: Information) } private final case class XpackSettings(securityEnabled: Boolean) @@ -145,8 +159,8 @@ object EsConfig { alternativePath = NonEmptyList.of("readonlyrest", "force_load_from_file"), // for a sake of backward compatibility default = false ) map { - case true => ForceLoadingFromFile - case false => LoadFromIndexWithFileFallback + case true => ??? + case false => ??? } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala index bf3f04967f..05d1e48a0b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala @@ -20,6 +20,7 @@ import better.files.File import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.FipsConfiguration.FipsMode import tech.beshu.ror.configuration.FipsConfiguration.FipsMode.NonFips import tech.beshu.ror.configuration.loader.FileConfigLoader @@ -33,7 +34,7 @@ final case class FipsConfiguration(fipsMode: FipsMode) object FipsConfiguration extends Logging { def load(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, FipsConfiguration]] = Task { + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, FipsConfiguration]] = Task { val esConfig = esEnv.elasticsearchConfig loadFipsConfigFromFile(esConfig) .fold( @@ -49,8 +50,8 @@ object FipsConfiguration extends Logging { } private def fallbackToRorConfig(esConfigFolderPath: Path) - (implicit environmentConfig: EnvironmentConfig) = { - val rorConfig = new FileConfigLoader(esConfigFolderPath).rawConfigFile + (implicit systemContext: SystemContext) = { + val rorConfig = new FileConfigLoader(???).rawConfigFile logger.info(s"... trying: ${rorConfig.show}") if (rorConfig.exists) { loadFipsConfigFromFile(rorConfig) @@ -60,7 +61,7 @@ object FipsConfiguration extends Logging { } private def loadFipsConfigFromFile(configFile: File) - (implicit environmentConfig: EnvironmentConfig): Either[MalformedSettings, FipsConfiguration] = { + (implicit systemContext: SystemContext): Either[MalformedSettings, FipsConfiguration] = { new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Settings") } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala index 39c7f63291..af49813a03 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala @@ -21,6 +21,7 @@ import cats.effect.Resource import cats.{Eq, Show} import io.circe.{Json, ParsingFailure} import monix.eval.Task +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.RawRorConfig.ParsingRorConfigError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.implicits.* @@ -31,15 +32,15 @@ final case class RawRorConfig(configJson: Json, raw: String) object RawRorConfig { def fromFile(file: File) - (implicit environmentConfig: EnvironmentConfig): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + (implicit systemContext: SystemContext): Task[Either[ParsingRorConfigError, RawRorConfig]] = { fromString(file.contentAsString) } def fromString(content: String) - (implicit environmentConfig: EnvironmentConfig): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + (implicit systemContext: SystemContext): Task[Either[ParsingRorConfigError, RawRorConfig]] = { val contentResource = Resource.make(Task(new StringReader(content))) { reader => Task(reader.close()) } contentResource.use { reader => Task { - handleParseResult(environmentConfig.yamlParser.parse(reader)) + handleParseResult(systemContext.yamlParser.parse(reader)) .map(RawRorConfig(_, content)) }} } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala index 2cfff86701..2e2d09b1f6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala @@ -18,6 +18,7 @@ package tech.beshu.ror.configuration import cats.data.EitherT import monix.eval.Task +import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.ScalaOps.* @@ -28,7 +29,7 @@ final case class ReadonlyRestEsConfig(bootConfig: RorBootConfiguration, object ReadonlyRestEsConfig { def load(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, ReadonlyRestEsConfig]] = { + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, ReadonlyRestEsConfig]] = { value { for { bootConfig <- EitherT(RorBootConfiguration.load(esEnv)) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala index a201517ff2..79093ae307 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala @@ -21,6 +21,7 @@ import cats.data.NonEmptyList import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* @@ -32,14 +33,14 @@ final case class RorBootConfiguration(rorNotStartedResponse: RorNotStartedRespon object RorBootConfiguration extends Logging { def load(env: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, RorBootConfiguration]] = Task { + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootConfiguration]] = Task { implicit val rorBootConfigurationDecoder: Decoder[RorBootConfiguration] = Decoders.decoder loadRorBootstrapConfig(env.elasticsearchConfig) } private def loadRorBootstrapConfig(configFile: File) (implicit decoder: Decoder[RorBootConfiguration], - environmentConfig: EnvironmentConfig) = { + systemContext: SystemContext) = { new YamlFileBasedConfigLoader(configFile).loadConfig[RorBootConfiguration](configName = "ROR boot configuration") } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 5589f1493e..7327ab3abf 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -20,6 +20,7 @@ import better.files.* import io.circe.{Decoder, DecodingFailure, HCursor} import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslConfiguration, InternodeSslConfiguration} import tech.beshu.ror.configuration.loader.FileConfigLoader @@ -38,7 +39,7 @@ object RorSsl extends Logging { val noSsl: RorSsl = RorSsl(None, None) def load(esEnv: EsEnv) - (implicit environmentConfig: EnvironmentConfig): Task[Either[MalformedSettings, RorSsl]] = Task { + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorSsl]] = Task { implicit val sslDecoder: Decoder[RorSsl] = SslDecoders.rorSslDecoder(esEnv.configPath) val esConfig = esEnv.elasticsearchConfig loadSslConfigFromFile(esConfig) @@ -56,8 +57,8 @@ object RorSsl extends Logging { private def fallbackToRorConfig(esConfigFolderPath: Path) (implicit rorSslDecoder: Decoder[RorSsl], - environmentConfig: EnvironmentConfig) = { - val rorConfig = new FileConfigLoader(esConfigFolderPath).rawConfigFile + systemContext: SystemContext) = { + val rorConfig = new FileConfigLoader(???).rawConfigFile logger.info(s"... trying: ${rorConfig.show}") if (rorConfig.exists) { loadSslConfigFromFile(rorConfig) @@ -68,7 +69,7 @@ object RorSsl extends Logging { private def loadSslConfigFromFile(configFile: File) (implicit rorSslDecoder: Decoder[RorSsl], - environmentConfig: EnvironmentConfig) = { + systemContext: SystemContext) = { new YamlFileBasedConfigLoader(configFile).loadConfig[RorSsl](configName = "ROR SSL settings") } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala index cf80fb2ce4..b4821418c2 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala @@ -18,17 +18,18 @@ package tech.beshu.ror.configuration import better.files.File import io.circe.{Decoder, DecodingFailure, Json} +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.factory.JsonConfigStaticVariableResolver import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson final class YamlFileBasedConfigLoader(file: File) - (implicit environmentConfig: EnvironmentConfig) { + (implicit systemContext: SystemContext) { private val jsonConfigResolver = new JsonConfigStaticVariableResolver( - environmentConfig.envVarsProvider, - TransformationCompiler.withoutAliases(environmentConfig.variablesFunctions) + systemContext.envVarsProvider, + TransformationCompiler.withoutAliases(systemContext.variablesFunctions) ) def loadConfig[CONFIG: Decoder](configName: String): Either[MalformedSettings, CONFIG] = { @@ -42,7 +43,7 @@ final class YamlFileBasedConfigLoader(file: File) private lazy val loadedConfigJson: Either[MalformedSettings, Json] = { file.fileReader { reader => - environmentConfig + systemContext .yamlParser .parse(reader) .left.map(e => MalformedSettings(s"Cannot parse file ${file.pathAsString.show} content. Cause: ${e.message.show}")) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala index 7b0795a1c3..af780967b2 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala @@ -18,8 +18,9 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, IndexConfigUnknownStructure} import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.ParsingError @@ -27,7 +28,7 @@ import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} final class IndexConfigManager(indexJsonContentService: IndexJsonContentService) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends BaseIndexConfigManager[RawRorConfig] with Logging { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala index fe31acdb28..d882dcb06b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala @@ -23,6 +23,7 @@ import io.circe.syntax.EncoderOps import io.circe.{Codec, Decoder, Encoder} import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks @@ -37,7 +38,7 @@ import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, import tech.beshu.ror.configuration.index.IndexTestConfigManager.Const import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, TestRorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, TestRorConfig} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} import tech.beshu.ror.syntax.* @@ -50,7 +51,7 @@ import scala.concurrent.duration.Duration import scala.util.Try final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentService) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends BaseIndexConfigManager[TestRorConfig] with Logging { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala index a8a48bb7ca..fd8ba84251 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala @@ -20,6 +20,7 @@ import cats.data.EitherT import cats.~> import monix.eval.Task import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.configuration.ConfigLoading.LoadConfigAction import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError @@ -29,14 +30,14 @@ import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError import tech.beshu.ror.configuration.loader.LoadedRorConfig.* -import tech.beshu.ror.configuration.{ConfigLoading, EnvironmentConfig, EsConfig} +import tech.beshu.ror.configuration.{ConfigLoading, EsConfig} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration object ConfigLoadingInterpreter extends Logging { def create(indexConfigManager: IndexConfigManager) - (implicit environmentConfig: EnvironmentConfig): LoadConfigAction ~> Task = new (LoadConfigAction ~> Task) { + (implicit systemContext: SystemContext): LoadConfigAction ~> Task = new (LoadConfigAction ~> Task) { override def apply[A](fa: LoadConfigAction[A]): Task[A] = fa match { case ConfigLoading.LoadConfigAction.LoadEsConfig(env) => logger.info(s"Loading Elasticsearch settings from file: ${env.elasticsearchConfig.show}") @@ -57,7 +58,7 @@ object ConfigLoadingInterpreter extends Logging { }) case ConfigLoading.LoadConfigAction.ForceLoadRorConfigFromFile(path) => logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${path.show}") - EitherT(new FileConfigLoader(path).load()) + EitherT(new FileConfigLoader(???).load()) .bimap(convertFileError, ForcedFileConfig(_)) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") @@ -65,7 +66,7 @@ object ConfigLoadingInterpreter extends Logging { }.value case ConfigLoading.LoadConfigAction.LoadRorConfigFromFile(path) => logger.info(s"Loading ReadonlyREST settings from file from: ${path.show}, because index not exist") - EitherT(new FileConfigLoader(path).load()) + EitherT(new FileConfigLoader(???).load()) .bimap(convertFileError, FileConfig(_)) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala index f441d0d42b..5dc1910f94 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala @@ -20,27 +20,20 @@ import better.files.File import cats.Show import cats.data.EitherT import monix.eval.Task +import tech.beshu.ror.SystemContext +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError.FileNotExist -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorProperties} -import tech.beshu.ror.providers.PropertiesProvider -import java.nio.file.Path - -class FileConfigLoader(esConfigPath: Path) - (implicit environmentConfig: EnvironmentConfig) +class FileConfigLoader(settings: LoadFromFileSettings) + (implicit systemContext: SystemContext) extends ConfigLoader[FileConfigError] { - private implicit val propertiesProvider: PropertiesProvider = environmentConfig.propertiesProvider - - def rawConfigFile: File = { - RorProperties.rorSettingsCustomFile match { - case Some(customRorFile) => customRorFile - case None => File(s"${esConfigPath.toAbsolutePath}/readonlyrest.yml") - } - } + // todo: do we need it? + def rawConfigFile: File = settings.rorSettingsFile override def load(): Task[Either[ConfigLoaderError[FileConfigError], RawRorConfig]] = { val file = rawConfigFile diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala index f557c7be96..a8c4e8c95a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala @@ -18,26 +18,27 @@ package tech.beshu.ror.configuration.loader.distributed import cats.data.EitherT import monix.eval.Task +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.ConfigLoading.LoadRorConfig import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.IndexConfigManager import tech.beshu.ror.configuration.loader.{ConfigLoadingInterpreter, LoadRawRorConfig, LoadedRorConfig} -import tech.beshu.ror.configuration.{ConfigLoading, EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.{ConfigLoading, RawRorConfig} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} object RawRorConfigLoadingAction { def loadFromIndex(env: EsEnv, indexJsonContentService: IndexJsonContentService) - (implicit environmentConfig: EnvironmentConfig): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + (implicit systemContext: SystemContext): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { val compiler = ConfigLoadingInterpreter.create(new IndexConfigManager(indexJsonContentService)) (for { esConfig <- EitherT(ConfigLoading.loadEsConfig(env)) loadedConfig <- esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile => + case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.leftT[LoadRorConfig, LoadedRorConfig[RawRorConfig]]( LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled("todo"): LoadedRorConfig.Error // todo: fixme ) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback => + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => EitherT(LoadRawRorConfig.loadFromIndex(esConfig.rorEsLevelSettings.rorConfigIndex)) } } yield loadedConfig).value.foldMap(compiler) diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 73b770df4a..20343eb9fe 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.providers.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -37,7 +37,7 @@ trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { protected implicit def propertiesProvider: TestsPropertiesProvider = TestsPropertiesProvider.default - private implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig( + private implicit val systemContext: SystemContext = new Environment( envVarsProvider = envVarsProvider, propertiesProvider = propertiesProvider ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index 85e15ae099..367f7c15df 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCre import tech.beshu.ror.accesscontrol.factory.{Core, RawRorConfigBasedCoreFactory} import tech.beshu.ror.audit.adapters.DeprecatedAuditLogSerializerAdapter import tech.beshu.ror.audit.instances.{DefaultAuditLogSerializer, QueryAuditLogSerializer} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} import tech.beshu.ror.es.EsVersion import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.utils.TestsUtils.* @@ -44,7 +44,7 @@ import scala.reflect.ClassTag class AuditSettingsTests extends AnyWordSpec with Inside { private def factory(esVersion: EsVersion = defaultEsVersionForTests) = { - implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + implicit val systemContext: SystemContext = SystemContext.default new RawRorConfigBasedCoreFactory(esVersion) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index 2982cc6393..ab733bcfe2 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockHttpClientsFactoryWithFixedHttpClient, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.TestsUtils.* @@ -39,7 +39,7 @@ import tech.beshu.ror.utils.TestsUtils.* class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { private val factory: CoreFactory = { - implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + implicit val systemContext: SystemContext = SystemContext.default new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 0c5d7bc7b9..e3b4200583 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.mocks.MockHttpClientsFactory import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers @@ -386,7 +386,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { } private val factory: CoreFactory = { - implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + implicit val systemContext: SystemContext = SystemContext.default new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index a02b11634b..5690b764e8 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -24,7 +24,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorConfigurationIndex, User} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig} +import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers @@ -318,7 +318,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { } private val factory = { - implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + implicit val systemContext: SystemContext = SystemContext.default new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala index c2332d1965..671687789a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.factory.{Core, HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.mocks.MockHttpClientsFactory import tech.beshu.ror.providers.* import tech.beshu.ror.utils.TestsUtils.* @@ -49,7 +49,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord protected implicit def envVarsProvider: EnvVarsProvider = OsEnvVarsProvider protected def factory: RawRorConfigBasedCoreFactory = { - implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig(envVarsProvider = envVarsProvider) + implicit val systemContext: SystemContext = new Environment(envVarsProvider = envVarsProvider) new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 6fd8a70399..99ceb6c1c8 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -47,7 +47,7 @@ import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, TestConfig import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.configuration.RorConfig.NoOpImpersonationWarningsReader import tech.beshu.ror.configuration.index.SavingIndexConfigError -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound, WriteError} @@ -1409,7 +1409,7 @@ class ReadonlyRestStartingTests .map(size => "com.readonlyrest.settings.maxSize" -> size) .toMap - implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig( + implicit val systemContext: SystemContext = new Environment( propertiesProvider = TestsPropertiesProvider.usingMap( mapWithIntervalFrom(refreshInterval) ++ mapWithMaxYamlSize(maxYamlSize) ++ diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index 680e69afdd..5de2b57ef1 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} import tech.beshu.ror.boot.RorInstance.TestConfig import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.{EnvironmentConfig, RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -217,7 +217,7 @@ class RorIndexTest extends AnyWordSpec private def readonlyRestBoot(factory: CoreFactory, indexJsonContentService: IndexJsonContentService, configPath: String) = { - implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig( + implicit val systemContext: SystemContext = new Environment( propertiesProvider = TestsPropertiesProvider.usingMap( Map( "com.readonlyrest.settings.loading.delay" -> "1" diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala index 2aa71815aa..df806921c2 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala @@ -21,14 +21,14 @@ import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} -import tech.beshu.ror.configuration.{EnvironmentConfig, MalformedSettings, RorBootConfiguration} +import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorBootConfiguration} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} class RorBootConfigurationTest extends AnyWordSpec with Inside { - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default "A ReadonlyREST ES starting settings" should { "be loaded from elasticsearch config file" when { diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala index 601ad0bbfd..32f9a9e2ab 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala @@ -22,7 +22,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.configuration.SslConfiguration.* import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} -import tech.beshu.ror.configuration.{EnvironmentConfig, MalformedSettings, RorSsl} +import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorSsl} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} @@ -30,7 +30,7 @@ import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePat class SslConfigurationTest extends AnyWordSpec with Inside { - private implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig( + private implicit val systemContext: SystemContext = new Environment( propertiesProvider = TestsPropertiesProvider.default ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala index 4c827606e3..a4d750f490 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala @@ -22,11 +22,11 @@ import io.circe.Decoder import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.configuration.{EnvironmentConfig, YamlFileBasedConfigLoader} +import tech.beshu.ror.configuration.{Environment, YamlFileBasedConfigLoader} class YamlFileBasedConfigLoaderTest extends AnyWordSpec with Inside { - private implicit val environmentConfig: EnvironmentConfig = new EnvironmentConfig( + private implicit val systemContext: SystemContext = new Environment( envVarsProvider = name => name.value.value match { case "USER_NAME" => Some("John") diff --git a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 70ec39bb92..3f17635035 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index bdc57e02ab..0168bd0d19 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index e4f65142ba..328935bbfb 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.settings.Settings import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -68,7 +68,7 @@ class TransportRRConfigAction(setting: Settings, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(setting: Settings, diff --git a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 70ec39bb92..3f17635035 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 99f22c3fd4..fdb13305d4 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 261715f8bb..384b40bce9 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.inject.Inject import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 92d9d36efc..6953fae982 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4fa8e3b224..ce9ff9e1ce 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 92d9d36efc..6953fae982 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4fa8e3b224..ce9ff9e1ce 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 92d9d36efc..6953fae982 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4fa8e3b224..ce9ff9e1ce 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 9b69a93a6b..9857631e73 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,13 +28,14 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +60,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +106,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 68be0eda0c..3fd08cabab 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -38,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,8 +50,8 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} -import tech.beshu.ror.constants +import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.{SystemContext, constants} import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1da6cd216f..07ee503ca8 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -66,7 +66,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 9b69a93a6b..a2a3ecbc56 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 0969040081..e603e10ee6 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1da6cd216f..07ee503ca8 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -66,7 +66,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 70ec39bb92..3f17635035 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 99f22c3fd4..fdb13305d4 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 261715f8bb..384b40bce9 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.inject.Inject import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 70ec39bb92..3f17635035 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 3dc935c5e7..7facfcdadd 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index bf4f9a51a1..ce49f5aae2 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.inject.Inject import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 70ec39bb92..3f17635035 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 97631c4544..e8bee73bb0 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 88b7eadc0e..cdc9b97e4e 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index be755de97f..c50e3feada 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index dadabcbd95..1077625840 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index bdb3318237..3ee12048dc 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -57,10 +57,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index a1f7bb2979..4636c90dd5 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -97,7 +97,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 92d9d36efc..6953fae982 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 720618abdc..534ae8efea 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index b6aea7a594..97cbeefff6 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.common.io.stream.{StreamInput, Writeable} import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 9b69a93a6b..a2a3ecbc56 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index eb152d06b5..3564d323ba 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 552456d44d..8236536367 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index f5a296c47a..43c6fe0d6a 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -52,7 +52,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -103,7 +103,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 6a08b286cb..0e55006e52 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -65,7 +65,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 61bfffb84d..8ff275872a 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -53,7 +53,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -104,7 +104,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1357e117f7..35dc2b9fea 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -66,7 +66,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 909aa98001..5eb518cb34 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -45,7 +45,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -96,7 +96,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 739ccc22bc..4632c6ded2 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b66bb4cc0b..0077fa9ffc 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -46,7 +46,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -97,7 +97,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 739ccc22bc..4632c6ded2 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b66bb4cc0b..0077fa9ffc 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -46,7 +46,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -97,7 +97,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 739ccc22bc..4632c6ded2 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 11f4e964a5..3d73191141 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 6e47a4e72d..cb309e058b 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -63,7 +63,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 53b96d3d7a..c688fa1c21 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 1466319cd4..a136d6f0e7 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index c0aba7ad0b..3d44057e51 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.injection.guice.Inject import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 1466319cd4..a136d6f0e7 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index c0aba7ad0b..3d44057e51 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.injection.guice.Inject import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 5ca08c04fc..2b2ec4ab23 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 56d0aa2cd3..8b2f8f7cb0 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 72d125413f..97ac49aa6f 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 5ca08c04fc..2b2ec4ab23 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 56d0aa2cd3..8b2f8f7cb0 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 72d125413f..97ac49aa6f 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 5ca08c04fc..2b2ec4ab23 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 655f06105c..704e92a3f5 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -98,7 +98,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 72d125413f..97ac49aa6f 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 5ca08c04fc..2b2ec4ab23 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -105,7 +105,7 @@ class IndexLevelActionFilter(nodeName: String, client, threadPool, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 637c4c4664..7b697970d2 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -99,7 +99,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s)) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 72d125413f..97ac49aa6f 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,7 +29,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 5637850e78..30c0db763d 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -102,7 +102,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index e545b4bc77..1341967a56 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4a1ce62068..2537b67619 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -102,7 +102,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index e545b4bc77..1341967a56 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 9d7027dcc8..06382c443e 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -102,7 +102,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index e545b4bc77..1341967a56 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc67647b0f..b36272726c 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -104,7 +104,7 @@ class IndexLevelActionFilter(nodeName: String, new NodeClientBasedAuditSinkService( client, new XContentJsonParserFactory(xContentRegistry) - )(using environmentConfig.clock) + )(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 9d7027dcc8..06382c443e 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -102,7 +102,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index e545b4bc77..1341967a56 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.env.Environment import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -67,7 +67,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index bdfbfae127..935d3f8369 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -59,10 +59,10 @@ class IndexLevelActionFilter(nodeName: String, repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) @@ -101,7 +101,7 @@ class IndexLevelActionFilter(nodeName: String, private def createService(cluster: AuditCluster): IndexBasedAuditSinkService & DataStreamBasedAuditSinkService = { cluster match { case AuditCluster.LocalAuditCluster => - new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry))(using environmentConfig.clock) + new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry))(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index feff7901a8..ec8018e604 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.configuration.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} @@ -97,7 +97,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 9d4371d974..f0ffb95859 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,7 +28,7 @@ import org.elasticsearch.injection.guice.Inject import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService @@ -62,7 +62,7 @@ class TransportRRConfigAction(actionName: String, import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default @Inject def this(actionName: String, From ef345467bcfd1d2ea5fb22863bfd9b0c3131de03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 30 Jun 2025 15:46:26 +0200 Subject: [PATCH 004/103] wip --- .../ror/accesscontrol/domain/indices.scala | 1 + .../tech/beshu/ror/boot/ReadonlyRest.scala | 32 ++++++++----------- .../tech/beshu/ror/boot/RorInstance.scala | 28 +++++++++------- .../ror/configuration/ConfigLoading.scala | 15 ++++----- .../beshu/ror/configuration/EsConfig.scala | 24 ++++++++++---- .../ror/configuration/FipsConfiguration.scala | 27 +++++++--------- .../configuration/ReadonlyRestEsConfig.scala | 8 +++-- .../ror/configuration/SslConfiguration.scala | 21 ++++++------ .../loader/ConfigLoadingInterpreter.scala | 14 ++++---- .../loader/FileConfigLoader.scala | 8 ++--- .../loader/LoadRawRorConfig.scala | 25 +++++++-------- 11 files changed, 103 insertions(+), 100 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala index 9f4f0eb2a4..4c9cff4c1a 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala @@ -526,6 +526,7 @@ object IndexAttribute { case object Closed extends IndexAttribute } +// todo: change name to RorSettingsIndex final case class RorConfigurationIndex(index: IndexName.Full) extends AnyVal { def toLocal: ClusterIndexName.Local = ClusterIndexName.Local(index) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index dd1557f63a..f9983d01cc 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -70,20 +70,14 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadRorConfig(esConfig: EsConfig) = { val action = esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - LoadRawRorConfig.loadFromFile(esEnv.configPath) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => - val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) - val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) - val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - LoadRawRorConfig - .loadFromIndexWithFileFallback( - configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = loadingAttemptsCount, - loadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfigFilePath = esEnv.configPath - ) + case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => + LoadRawRorConfig.loadFromFile(settings) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => + // todo: move +// val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) +// val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) +// val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) + LoadRawRorConfig.loadFromIndexWithFileFallback(settings, fallbackSettings) } runStartingFailureProgram(action) } @@ -158,7 +152,7 @@ class ReadonlyRest(coreFactory: CoreFactory, for { mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorEsLevelSettings.rorConfigIndex)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) - rorInstance <- createRorInstance(esConfig.rorEsLevelSettings.rorConfigIndex, mainEngine, testEngine, loadedConfig) + rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, loadedConfig) } yield rorInstance } @@ -203,18 +197,18 @@ class ReadonlyRest(coreFactory: CoreFactory, TestEngine.Expiration(config.ttl, config.validTo) } - private def createRorInstance(rorConfigurationIndex: RorConfigurationIndex, + private def createRorInstance(esConfig: EsConfig, engine: Engine, testEngine: TestEngine, loadedConfig: LoadedRorConfig[RawRorConfig]) = { EitherT.right[StartingFailure] { loadedConfig match { case LoadedRorConfig.FileConfig(config) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, rorConfigurationIndex) + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) case LoadedRorConfig.ForcedFileConfig(config) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, rorConfigurationIndex) + RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) case LoadedRorConfig.IndexConfig(_, config) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, rorConfigurationIndex) + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 1e8a4dcebf..4b0972e689 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.boot +import better.files.File import cats.Show import cats.effect.Resource import cats.implicits.toShow @@ -45,7 +46,8 @@ class RorInstance private(boot: ReadonlyRest, mainReloadInProgress: Semaphore[Task], initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], - rorConfigurationIndex: RorConfigurationIndex) + rorSettingsIndex: RorConfigurationIndex, + rorSettingsFile: File) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -72,20 +74,20 @@ class RorInstance private(boot: ReadonlyRest, boot, (initialEngine.engine, initialEngine.config), mainReloadInProgress, - rorConfigurationIndex, + rorSettingsIndex, ) private val anTestConfigEngine = TestConfigBasedReloadableEngine.create( boot, initialTestEngine, testReloadInProgress, - rorConfigurationIndex + rorSettingsIndex ) private val configRestApi = new ConfigApi( rorInstance = this, boot.indexConfigManager, - new FileConfigLoader(???), - rorConfigurationIndex + new FileConfigLoader(rorSettingsFile), + rorSettingsIndex ) private val authMockRestApi = new AuthMockApi( @@ -271,26 +273,29 @@ object RorInstance { def createWithPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - rorConfigurationIndex: RorConfigurationIndex) + rorSettingsFile: File, + rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.WithPeriodicIndexCheck, mainEngine, testEngine, rorConfigurationIndex) + create(boot, Mode.WithPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - rorConfigurationIndex: RorConfigurationIndex) + rorSettingsFile: File, + rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorConfigurationIndex) + create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) } private def create(boot: ReadonlyRest, mode: RorInstance.Mode, engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - rorConfigurationIndex: RorConfigurationIndex) + rorSettingsFile: File, + rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { @@ -303,7 +308,8 @@ object RorInstance { mainReloadInProgress = isReloadInProgressSemaphore, initialTestEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, - rorConfigurationIndex = rorConfigurationIndex + rorSettingsIndex = rorSettingsIndex, + rorSettingsFile = rorSettingsFile ) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala index 62e0711062..eaed6a0044 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala @@ -18,13 +18,12 @@ package tech.beshu.ror.configuration import cats.free.Free import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.configuration.loader.LoadedRorConfig import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration -import java.nio.file.Path - object ConfigLoading { type ErrorOr[A] = LoadedRorConfig.Error Either A type IndexErrorOr[A] = LoadedRorConfig.LoadingIndexError Either A @@ -34,9 +33,9 @@ object ConfigLoading { object LoadConfigAction { final case class LoadEsConfig(env: EsEnv) extends LoadConfigAction[ErrorOr[EsConfig]] - final case class ForceLoadRorConfigFromFile(path: Path) + final case class ForceLoadRorConfigFromFile(settings: LoadFromFileSettings) extends LoadConfigAction[ErrorOr[ForcedFileConfig[RawRorConfig]]] - final case class LoadRorConfigFromFile(path: Path) + final case class LoadRorConfigFromFile(settings: LoadFromFileSettings) extends LoadConfigAction[ErrorOr[FileConfig[RawRorConfig]]] final case class LoadRorConfigFromIndex(index: RorConfigurationIndex, loadingDelay: NonNegativeFiniteDuration) extends LoadConfigAction[IndexErrorOr[IndexConfig[RawRorConfig]]] @@ -46,13 +45,13 @@ object ConfigLoading { loadingDelay: NonNegativeFiniteDuration): LoadRorConfig[IndexErrorOr[IndexConfig[RawRorConfig]]] = Free.liftF(LoadConfigAction.LoadRorConfigFromIndex(index, loadingDelay)) - def loadRorConfigFromFile(path: Path): LoadRorConfig[ErrorOr[FileConfig[RawRorConfig]]] = - Free.liftF(LoadConfigAction.LoadRorConfigFromFile(path)) + def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[FileConfig[RawRorConfig]]] = + Free.liftF(LoadConfigAction.LoadRorConfigFromFile(settings)) def loadEsConfig(env: EsEnv): LoadRorConfig[ErrorOr[EsConfig]] = Free.liftF(LoadConfigAction.LoadEsConfig(env)) - def forceLoadRorConfigFromFile(path: Path): LoadRorConfig[ErrorOr[ForcedFileConfig[RawRorConfig]]] = - Free.liftF(LoadConfigAction.ForceLoadRorConfigFromFile(path)) + def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[ForcedFileConfig[RawRorConfig]]] = + Free.liftF(LoadConfigAction.ForceLoadRorConfigFromFile(settings)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala index 171545cfdf..d8d8702977 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadingRorCoreStrategy} import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.FipsConfiguration.FipsMode import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} @@ -56,8 +56,12 @@ object EsConfig { loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex xpackSettings <- loadXpackSettings(esEnv, esEnv.isOssDistribution) - sslSettings <- loadSslSettings(esEnv, xpackSettings) - fibsConfiguration <- loadFipsConfiguration(esEnv, xpackSettings) + rorFileSettings = loadingRorCoreStrategy match { + case ForceLoadingFromFile(settings) => settings + case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings + } + sslSettings <- loadSslSettings(esEnv, rorFileSettings, xpackSettings) + fibsConfiguration <- loadFipsConfiguration(esEnv, rorFileSettings, xpackSettings) } yield RorEsLevelSettings(rorIndex, loadingRorCoreStrategy, sslSettings, fibsConfiguration) } @@ -71,9 +75,9 @@ object EsConfig { } } - private def loadSslSettings(esEnv: EsEnv, xpackSettings: XpackSettings) + private def loadSslSettings(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, RorSsl] = { - EitherT(RorSsl.load(esEnv)) + EitherT(RorSsl.load(esEnv, rorFileSettings)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) .subflatMap { rorSsl => if (rorSsl != RorSsl.noSsl && xpackSettings.securityEnabled) { @@ -84,9 +88,9 @@ object EsConfig { } } - private def loadFipsConfiguration(esEnv: EsEnv, xpackSettings: XpackSettings) + private def loadFipsConfiguration(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, FipsConfiguration] = { - EitherT(FipsConfiguration.load(esEnv)) + EitherT(FipsConfiguration.load(esEnv, rorFileSettings)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) .subflatMap { fipsConfiguration => fipsConfiguration.fipsMode match { @@ -127,6 +131,12 @@ object EsConfig { extends LoadingRorCoreStrategy } + implicit class RorSettingsFileFromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { + def rorSettingsFile: File = strategy match + case ForceLoadingFromFile(settings) => settings.rorSettingsFile + case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings.rorSettingsFile + } + final case class LoadFromFileSettings(rorSettingsFile: File, settingsMaxSize: Information) final case class LoadFromIndexSettings(rorConfigIndex: RorConfigurationIndex, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala index 05d1e48a0b..cef0eddc71 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala @@ -21,19 +21,17 @@ import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.configuration.FipsConfiguration.FipsMode import tech.beshu.ror.configuration.FipsConfiguration.FipsMode.NonFips -import tech.beshu.ror.configuration.loader.FileConfigLoader import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* -import java.nio.file.Path - final case class FipsConfiguration(fipsMode: FipsMode) object FipsConfiguration extends Logging { - def load(esEnv: EsEnv) + def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, FipsConfiguration]] = Task { val esConfig = esEnv.elasticsearchConfig loadFipsConfigFromFile(esConfig) @@ -42,29 +40,28 @@ object FipsConfiguration extends Logging { { case FipsConfiguration(FipsMode.NonFips) => logger.info(s"Cannot find FIPS configuration in ${esConfig.show} ...") - fallbackToRorConfig(esEnv.configPath) + fallbackToRorConfig(loadRorFromFileSettings.rorSettingsFile) case ssl => Right(ssl) } ) } - private def fallbackToRorConfig(esConfigFolderPath: Path) + private def loadFipsConfigFromFile(configFile: File) + (implicit systemContext: SystemContext): Either[MalformedSettings, FipsConfiguration] = { + new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Settings") + } + + private def fallbackToRorConfig(rorSettingsFile: File) (implicit systemContext: SystemContext) = { - val rorConfig = new FileConfigLoader(???).rawConfigFile - logger.info(s"... trying: ${rorConfig.show}") - if (rorConfig.exists) { - loadFipsConfigFromFile(rorConfig) + logger.info(s"... trying: ${rorSettingsFile.show}") + if (rorSettingsFile.exists) { + loadFipsConfigFromFile(rorSettingsFile) } else { Right(FipsConfiguration(FipsMode.NonFips)) } } - private def loadFipsConfigFromFile(configFile: File) - (implicit systemContext: SystemContext): Either[MalformedSettings, FipsConfiguration] = { - new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Settings") - } - private implicit val fipsModeDecoder: Decoder[FipsMode] = { Decoder.decodeString.emap { case "NON_FIPS" => Right(FipsMode.NonFips) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala index 2e2d09b1f6..df260cc178 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala @@ -19,6 +19,7 @@ package tech.beshu.ror.configuration import cats.data.EitherT import monix.eval.Task import tech.beshu.ror.SystemContext +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.ScalaOps.* @@ -28,13 +29,14 @@ final case class ReadonlyRestEsConfig(bootConfig: RorBootConfiguration, object ReadonlyRestEsConfig { - def load(esEnv: EsEnv) + // todo: do we need it? + def load(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, ReadonlyRestEsConfig]] = { value { for { bootConfig <- EitherT(RorBootConfiguration.load(esEnv)) - sslConfig <- EitherT(RorSsl.load(esEnv)) - fipsConfig <- EitherT(FipsConfiguration.load(esEnv)) + sslConfig <- EitherT(RorSsl.load(esEnv, rorFileSettings)) + fipsConfig <- EitherT(FipsConfiguration.load(esEnv, rorFileSettings)) } yield ReadonlyRestEsConfig(bootConfig, sslConfig, fipsConfig) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 7327ab3abf..875d97c808 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -22,8 +22,8 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslConfiguration, InternodeSslConfiguration} -import tech.beshu.ror.configuration.loader.FileConfigLoader import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.SSLCertHelper @@ -38,30 +38,29 @@ object RorSsl extends Logging { val noSsl: RorSsl = RorSsl(None, None) - def load(esEnv: EsEnv) + def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorSsl]] = Task { implicit val sslDecoder: Decoder[RorSsl] = SslDecoders.rorSslDecoder(esEnv.configPath) - val esConfig = esEnv.elasticsearchConfig - loadSslConfigFromFile(esConfig) + val esConfigFile = esEnv.elasticsearchConfig + loadSslConfigFromFile(esConfigFile) .fold( error => Left(error), { case RorSsl(None, None) => - logger.info(s"Cannot find SSL configuration in ${esConfig.show} ...") - fallbackToRorConfig(esEnv.configPath) + logger.info(s"Cannot find SSL configuration in ${esConfigFile.show} ...") + fallbackToRorConfig(loadRorFromFileSettings.rorSettingsFile) case ssl => Right(ssl) } ) } - private def fallbackToRorConfig(esConfigFolderPath: Path) + private def fallbackToRorConfig(rorSettingsFile: File) (implicit rorSslDecoder: Decoder[RorSsl], systemContext: SystemContext) = { - val rorConfig = new FileConfigLoader(???).rawConfigFile - logger.info(s"... trying: ${rorConfig.show}") - if (rorConfig.exists) { - loadSslConfigFromFile(rorConfig) + logger.info(s"... trying: ${rorSettingsFile.show}") + if (rorSettingsFile.exists) { + loadSslConfigFromFile(rorSettingsFile) } else { Right(RorSsl.noSsl) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala index fd8ba84251..92418d34a9 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala @@ -56,17 +56,19 @@ object ConfigLoadingInterpreter extends Logging { } ) }) - case ConfigLoading.LoadConfigAction.ForceLoadRorConfigFromFile(path) => - logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${path.show}") - EitherT(new FileConfigLoader(???).load()) + case ConfigLoading.LoadConfigAction.ForceLoadRorConfigFromFile(settings) => + val rorSettingsFile = settings.rorSettingsFile + logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") + EitherT(new FileConfigLoader(rorSettingsFile).load()) .bimap(convertFileError, ForcedFileConfig(_)) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") error }.value - case ConfigLoading.LoadConfigAction.LoadRorConfigFromFile(path) => - logger.info(s"Loading ReadonlyREST settings from file from: ${path.show}, because index not exist") - EitherT(new FileConfigLoader(???).load()) + case ConfigLoading.LoadConfigAction.LoadRorConfigFromFile(settings) => + val rorSettingsFile = settings.rorSettingsFile + logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") + EitherT(new FileConfigLoader(rorSettingsFile).load()) .bimap(convertFileError, FileConfig(_)) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala index 5dc1910f94..7eb14b4c47 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala @@ -21,22 +21,18 @@ import cats.Show import cats.data.EitherT import monix.eval.Task import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError.FileNotExist -class FileConfigLoader(settings: LoadFromFileSettings) +class FileConfigLoader(rorSettingsFile: File) (implicit systemContext: SystemContext) extends ConfigLoader[FileConfigError] { - // todo: do we need it? - def rawConfigFile: File = settings.rorSettingsFile - override def load(): Task[Either[ConfigLoaderError[FileConfigError], RawRorConfig]] = { - val file = rawConfigFile + val file = rorSettingsFile (for { _ <- checkIfFileExist(file) config <- loadConfigFromFile(file) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index c2eddd57c5..4f7a62dde1 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -19,12 +19,12 @@ package tech.beshu.ror.configuration.loader import cats.free.Free import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.configuration.ConfigLoading.* +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} import tech.beshu.ror.configuration.loader.LoadedRorConfig.FileConfig import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, RefinedDurationOps} -import java.nio.file.Path import scala.concurrent.duration.DurationInt import scala.language.postfixOps @@ -32,23 +32,20 @@ object LoadRawRorConfig { type LoadResult = ErrorOr[LoadedRorConfig[RawRorConfig]] - def loadFromIndexWithFileFallback(configurationIndex: RorConfigurationIndex, - loadingDelay: LoadingDelay, - loadingAttemptsCount: LoadingAttemptsCount, - loadingAttemptsInterval: LoadingAttemptsInterval, - fallbackConfigFilePath: Path): LoadRorConfig[LoadResult] = { + def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, + fallbackFileLoadingSettings: LoadFromFileSettings): LoadRorConfig[LoadResult] = { attemptLoadingConfigFromIndex( - index = configurationIndex, - currentDelay = loadingDelay.value, - attemptsCount = loadingAttemptsCount, - attemptsInterval = loadingAttemptsInterval, - fallback = loadRorConfigFromFile(fallbackConfigFilePath) + index = indexLoadingSettings.rorConfigIndex, + currentDelay = indexLoadingSettings.loadingDelay.value, + attemptsCount = indexLoadingSettings.loadingAttemptsCount, + attemptsInterval = indexLoadingSettings.loadingAttemptsInterval, + fallback = loadRorConfigFromFile(fallbackFileLoadingSettings) ) } - def loadFromFile(configFilePath: Path): LoadRorConfig[LoadResult] = { + def loadFromFile(settings: LoadFromFileSettings): LoadRorConfig[LoadResult] = { for { - loadedConfig <- forceLoadRorConfigFromFile(configFilePath) + loadedConfig <- forceLoadRorConfigFromFile(settings) } yield loadedConfig } From 3252b49e87f3f0ca8ddb74c44cc3bda00e54ca00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 1 Jul 2025 15:13:39 +0200 Subject: [PATCH 005/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 49 +++++------ .../tech/beshu/ror/boot/RorInstance.scala | 19 ++--- .../ror/configuration/ConfigLoading.scala | 13 ++- .../ror/configuration/TestConfigLoading.scala | 4 +- .../loader/ConfigLoadingInterpreter.scala | 6 +- .../loader/LoadRawRorConfig.scala | 3 +- .../loader/LoadRawTestRorConfig.scala | 18 ++-- .../loader/TestConfigLoadingInterpreter.scala | 2 +- .../loader/distributed/Summary.scala | 2 +- .../internode/dto/LoadedConfigDTO.scala | 83 +------------------ .../ror/configuration/loader/domain.scala | 11 +-- .../loader/external/dto/LoadedConfigDTO.scala | 30 +------ .../ror/configuration/loader/package.scala | 22 +---- 13 files changed, 60 insertions(+), 202 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index f9983d01cc..f15ad2f3a6 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -74,9 +74,9 @@ class ReadonlyRest(coreFactory: CoreFactory, LoadRawRorConfig.loadFromFile(settings) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => // todo: move -// val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) -// val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) -// val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) + // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) + // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) + // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) LoadRawRorConfig.loadFromIndexWithFileFallback(settings, fallbackSettings) } runStartingFailureProgram(action) @@ -85,19 +85,16 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadRorTestConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - EitherT.right(Task.now(LoadedTestRorConfig.FallbackConfig(TestRorConfig.NotSet))) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => - val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) - val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) - val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - val action = LoadRawTestRorConfig - .loadFromIndexWithFallback( - configurationIndex = esConfig.rorEsLevelSettings.rorConfigIndex, - loadingDelay = loadingDelay, - indexLoadingAttemptsCount = loadingAttemptsCount, - indexLoadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfig = notSetTestRorConfig - ) + EitherT.right(Task.now(LoadedTestRorConfig(TestRorConfig.NotSet))) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => + // todo: move + // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) + // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) + // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) + val action = LoadRawTestRorConfig.loadFromIndexWithFallback( + indexLoadingSettings = settings, + fallbackConfig = notSetTestRorConfig + ) EitherT.right(runTestProgram(action)) } } @@ -135,13 +132,13 @@ class ReadonlyRest(coreFactory: CoreFactory, .leftMap { case LoadedTestRorConfig.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - LoadedTestRorConfig.FallbackConfig(notSetTestRorConfig) + LoadedTestRorConfig(notSetTestRorConfig) case LoadedTestRorConfig.IndexUnknownStructure => logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - LoadedTestRorConfig.FallbackConfig(notSetTestRorConfig) + LoadedTestRorConfig(notSetTestRorConfig) case LoadedTestRorConfig.IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - LoadedTestRorConfig.FallbackConfig(notSetTestRorConfig) + LoadedTestRorConfig(notSetTestRorConfig) } .merge } @@ -202,13 +199,13 @@ class ReadonlyRest(coreFactory: CoreFactory, testEngine: TestEngine, loadedConfig: LoadedRorConfig[RawRorConfig]) = { EitherT.right[StartingFailure] { - loadedConfig match { - case LoadedRorConfig.FileConfig(config) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) - case LoadedRorConfig.ForcedFileConfig(config) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) - case LoadedRorConfig.IndexConfig(_, config) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, config), testEngine, esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile, esConfig.rorEsLevelSettings.rorConfigIndex) + val rorSettingsFile = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile + val rorConfigIndex = esConfig.rorEsLevelSettings.rorConfigIndex + esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => + RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, rorSettingsFile, rorConfigIndex) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, settings.refreshInterval, rorSettingsFile, rorConfigIndex) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 4b0972e689..8307b88439 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.configuration.RorProperties.RefreshInterval import tech.beshu.ror.configuration.index.{IndexConfigError, SavingIndexConfigError} import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError import tech.beshu.ror.configuration.loader.FileConfigLoader -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig, RorProperties} +import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -57,15 +57,9 @@ class RorInstance private(boot: ReadonlyRest, logger.info("ReadonlyREST was loaded ...") private val configsReloadTask = mode match { - case Mode.WithPeriodicIndexCheck => - RorProperties.rorIndexSettingsReloadInterval(systemContext.propertiesProvider) match { - case RefreshInterval.Disabled => - logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") - Cancelable.empty - case RefreshInterval.Enabled(interval) => - scheduleEnginesReload(interval) - } - case Mode.NoPeriodicIndexCheck => + case Mode.WithPeriodicIndexCheck(RefreshInterval.Enabled(interval)) => + scheduleEnginesReload(interval) + case Mode.WithPeriodicIndexCheck(RefreshInterval.Disabled) | Mode.NoPeriodicIndexCheck => logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") Cancelable.empty } @@ -273,11 +267,12 @@ object RorInstance { def createWithPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, + refreshInterval: RefreshInterval, rorSettingsFile: File, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.WithPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) + create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, @@ -315,7 +310,7 @@ object RorInstance { private sealed trait Mode private object Mode { - case object WithPeriodicIndexCheck extends Mode + final case class WithPeriodicIndexCheck(reloadInterval: RefreshInterval) extends Mode case object NoPeriodicIndexCheck extends Mode } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala index eaed6a0044..13cfeb28d5 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala @@ -20,7 +20,6 @@ import cats.free.Free import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration @@ -34,24 +33,24 @@ object ConfigLoading { final case class LoadEsConfig(env: EsEnv) extends LoadConfigAction[ErrorOr[EsConfig]] final case class ForceLoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadConfigAction[ErrorOr[ForcedFileConfig[RawRorConfig]]] + extends LoadConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] final case class LoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadConfigAction[ErrorOr[FileConfig[RawRorConfig]]] + extends LoadConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] final case class LoadRorConfigFromIndex(index: RorConfigurationIndex, loadingDelay: NonNegativeFiniteDuration) - extends LoadConfigAction[IndexErrorOr[IndexConfig[RawRorConfig]]] + extends LoadConfigAction[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] } def loadRorConfigFromIndex(index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration): LoadRorConfig[IndexErrorOr[IndexConfig[RawRorConfig]]] = + loadingDelay: NonNegativeFiniteDuration): LoadRorConfig[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] = Free.liftF(LoadConfigAction.LoadRorConfigFromIndex(index, loadingDelay)) - def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[FileConfig[RawRorConfig]]] = + def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = Free.liftF(LoadConfigAction.LoadRorConfigFromFile(settings)) def loadEsConfig(env: EsEnv): LoadRorConfig[ErrorOr[EsConfig]] = Free.liftF(LoadConfigAction.LoadEsConfig(env)) - def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[ForcedFileConfig[RawRorConfig]]] = + def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = Free.liftF(LoadConfigAction.ForceLoadRorConfigFromFile(settings)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala index 5b95cc66ad..aa01b72c5e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala @@ -28,11 +28,11 @@ object TestConfigLoading { sealed trait LoadTestConfigAction[A] object LoadTestConfigAction { final case class LoadRorConfigFromIndex(index: RorConfigurationIndex, loadingDelay: NonNegativeFiniteDuration) - extends LoadTestConfigAction[IndexErrorOr[LoadedTestRorConfig.IndexConfig[TestRorConfig]]] + extends LoadTestConfigAction[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] } def loadRorConfigFromIndex(index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig.IndexConfig[TestRorConfig]]] = + loadingDelay: NonNegativeFiniteDuration): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = Free.liftF(LoadTestConfigAction.LoadRorConfigFromIndex(index, loadingDelay)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala index 92418d34a9..109db32200 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala @@ -60,7 +60,7 @@ object ConfigLoadingInterpreter extends Logging { val rorSettingsFile = settings.rorSettingsFile logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") EitherT(new FileConfigLoader(rorSettingsFile).load()) - .bimap(convertFileError, ForcedFileConfig(_)) + .bimap(convertFileError, LoadedRorConfig.apply) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") error @@ -69,7 +69,7 @@ object ConfigLoadingInterpreter extends Logging { val rorSettingsFile = settings.rorSettingsFile logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") EitherT(new FileConfigLoader(rorSettingsFile).load()) - .bimap(convertFileError, FileConfig(_)) + .bimap(convertFileError, LoadedRorConfig.apply) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") error @@ -82,7 +82,7 @@ object ConfigLoadingInterpreter extends Logging { logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") rawRorConfig } - .bimap(convertIndexError, IndexConfig(configIndex, _)) + .bimap(convertIndexError, LoadedRorConfig.apply) .leftMap { error => logIndexLoadingError(error) error diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index 4f7a62dde1..0a5b1a7807 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -22,7 +22,6 @@ import tech.beshu.ror.configuration.ConfigLoading.* import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} -import tech.beshu.ror.configuration.loader.LoadedRorConfig.FileConfig import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, RefinedDurationOps} import scala.concurrent.duration.DurationInt @@ -69,7 +68,7 @@ object LoadRawRorConfig { currentDelay: NonNegativeFiniteDuration, attemptsCount: LoadingAttemptsCount, attemptsInterval: LoadingAttemptsInterval, - fallback: LoadRorConfig[ErrorOr[FileConfig[RawRorConfig]]]): LoadRorConfig[LoadResult] = { + fallback: LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]]): LoadRorConfig[LoadResult] = { attemptsCount.value.value match { case 0 => fallback.map(identity) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala index 86382c37d4..39190f2b35 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala @@ -18,23 +18,21 @@ package tech.beshu.ror.configuration.loader import cats.free.Free import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} import tech.beshu.ror.configuration.TestConfigLoading.* import tech.beshu.ror.configuration.TestRorConfig import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration object LoadRawTestRorConfig { - def loadFromIndexWithFallback(configurationIndex: RorConfigurationIndex, - loadingDelay: LoadingDelay, - indexLoadingAttemptsCount: LoadingAttemptsCount, - indexLoadingAttemptsInterval: LoadingAttemptsInterval, + def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, fallbackConfig: TestRorConfig): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = { attemptLoadingConfigFromIndex( - index = configurationIndex, - currentDelay = loadingDelay.value, - attemptsCount = indexLoadingAttemptsCount, - attemptsInterval = indexLoadingAttemptsInterval, + index = indexLoadingSettings.rorConfigIndex, + currentDelay = indexLoadingSettings.loadingDelay.value, + attemptsCount = indexLoadingSettings.loadingAttemptsCount, + attemptsInterval = indexLoadingSettings.loadingAttemptsInterval, fallback = fallbackConfig ) } @@ -47,7 +45,7 @@ object LoadRawTestRorConfig { attemptsCount.value.value match { case 0 => Free.pure[LoadTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]( - Right(LoadedTestRorConfig.FallbackConfig[TestRorConfig](fallback)) + Right(LoadedTestRorConfig[TestRorConfig](fallback)) ) case attemptsCount => for { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala index 1325459dba..dddd71f990 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala @@ -46,7 +46,7 @@ object TestConfigLoadingInterpreter extends Logging { } testConfig } - .bimap(convertIndexError, IndexConfig(configIndex, _)) + .bimap(convertIndexError, LoadedTestRorConfig.apply) .leftMap { error => logIndexLoadingError(error) error diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala index 8bede481f6..3e9e42f45d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala @@ -93,7 +93,7 @@ object Summary { private def createNodeNodeForcedFileConfigWarnings(otherResponses: List[NodeResponse]): List[NodeForcedFileConfig] = otherResponses.flatMap { - case NodeResponse(nodeId, Right(LoadedRorConfig.ForcedFileConfig(_))) => NodeForcedFileConfig(nodeId) :: Nil + case NodeResponse(nodeId, Right(LoadedRorConfig(_))) => NodeForcedFileConfig(nodeId) :: Nil case _ => Nil } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala index 3e5e8925a7..37ef328275 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala @@ -16,89 +16,12 @@ */ package tech.beshu.ror.configuration.loader.distributed.internode.dto -import eu.timepit.refined.types.string.NonEmptyString -import io.circe.* -import io.circe.syntax.EncoderOps -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.utils.CirceOps.* - -import scala.collection.immutable.Map - -sealed trait LoadedConfigDTO +final case class LoadedConfigDTO(value: String) object LoadedConfigDTO { - implicit val codec: Codec[LoadedConfigDTO] = codecWithTypeDiscriminator( - encode = { - case dto: IndexConfigDTO => - derivedEncoderWithType[IndexConfigDTO]("IndexConfigDTO")(dto) - case dto: FileConfigDTO => - derivedEncoderWithType[FileConfigDTO]("FileConfigDTO")(dto) - case dto: ForcedFileConfigDTO => - derivedEncoderWithType[ForcedFileConfigDTO]("ForcedFileConfigDTO")(dto) - }, - decoders = Map( - "IndexConfigDTO" -> derivedDecoderOfSubtype[LoadedConfigDTO, IndexConfigDTO], - "FileConfigDTO" -> derivedDecoderOfSubtype[LoadedConfigDTO, FileConfigDTO], - "ForcedFileConfigDTO" -> derivedDecoderOfSubtype[LoadedConfigDTO, ForcedFileConfigDTO], - ) - ) - - def create(o: LoadedRorConfig[String]): LoadedConfigDTO = o match { - case o: LoadedRorConfig.FileConfig[String] => FileConfigDTO.create(o) - case o: LoadedRorConfig.ForcedFileConfig[String] => ForcedFileConfigDTO.create(o) - case o: LoadedRorConfig.IndexConfig[String] => IndexConfigDTO.create(o) - } - - def fromDto(o: LoadedConfigDTO): LoadedRorConfig[String] = o match { - case o: IndexConfigDTO => IndexConfigDTO.fromDto(o) - case o: FileConfigDTO => FileConfigDTO.fromDto(o) - case o: ForcedFileConfigDTO => ForcedFileConfigDTO.fromDto(o) - } - - final case class IndexConfigDTO(indexName: String, value: String) extends LoadedConfigDTO - object IndexConfigDTO { - def create(o: LoadedRorConfig.IndexConfig[String]): IndexConfigDTO = - new IndexConfigDTO( - indexName = o.indexName.index.name.value, - value = o.value, - ) - - def fromDto(o: IndexConfigDTO): LoadedRorConfig.IndexConfig[String] = LoadedRorConfig.IndexConfig( - indexName = RorConfigurationIndex(IndexName.Full(NonEmptyString.unsafeFrom(o.indexName))), - value = o.value, - ) - implicit class Ops(o: IndexConfigDTO) { - implicit def fromDto: LoadedRorConfig.IndexConfig[String] = IndexConfigDTO.fromDto(o) - } - } - final case class FileConfigDTO(value: String) extends LoadedConfigDTO - object FileConfigDTO { - def create(o: LoadedRorConfig.FileConfig[String]): FileConfigDTO = - new FileConfigDTO( - value = o.value, - ) - - def fromDto(o: FileConfigDTO): LoadedRorConfig.FileConfig[String] = LoadedRorConfig.FileConfig( - value = o.value, - ) - implicit class Ops(o: FileConfigDTO) { - implicit def fromDto: LoadedRorConfig.FileConfig[String] = FileConfigDTO.fromDto(o) - } - } - final case class ForcedFileConfigDTO(value: String) extends LoadedConfigDTO - object ForcedFileConfigDTO { - def create(o: LoadedRorConfig.ForcedFileConfig[String]): ForcedFileConfigDTO = - new ForcedFileConfigDTO( - value = o.value, - ) + def create(o: LoadedRorConfig[String]): LoadedConfigDTO = LoadedConfigDTO(o.value) - def fromDto(o: ForcedFileConfigDTO): LoadedRorConfig.ForcedFileConfig[String] = LoadedRorConfig.ForcedFileConfig( - value = o.value, - ) - implicit class Ops(o: ForcedFileConfigDTO) { - implicit def fromDto: LoadedRorConfig.ForcedFileConfig[String] = ForcedFileConfigDTO.fromDto(o) - } - } + def fromDto(o: LoadedConfigDTO): LoadedRorConfig[String] = LoadedRorConfig(o.value) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala index 637ea1d874..787611385e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala @@ -16,15 +16,10 @@ */ package tech.beshu.ror.configuration.loader -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex - import java.nio.file.Path -sealed trait LoadedRorConfig[A] +final case class LoadedRorConfig[A](value: A) object LoadedRorConfig { - final case class FileConfig[A](value: A) extends LoadedRorConfig[A] - final case class ForcedFileConfig[A](value: A) extends LoadedRorConfig[A] - final case class IndexConfig[A](indexName: RorConfigurationIndex, value: A) extends LoadedRorConfig[A] sealed trait Error final case class FileParsingError(message: String) extends LoadedRorConfig.Error @@ -39,10 +34,8 @@ object LoadedRorConfig { case object IndexNotExist extends LoadedRorConfig.Error with LoadingIndexError } -sealed trait LoadedTestRorConfig[A] +final case class LoadedTestRorConfig[A](value: A) object LoadedTestRorConfig { - final case class IndexConfig[A](indexName: RorConfigurationIndex, value: A) extends LoadedTestRorConfig[A] - final case class FallbackConfig[A](value: A) extends LoadedTestRorConfig[A] sealed trait LoadingIndexError final case class IndexParsingError(message: String) extends LoadingIndexError diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala index 9a2c41ebed..63e3a97f15 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala @@ -16,37 +16,11 @@ */ package tech.beshu.ror.configuration.loader.external.dto -import io.circe.Codec import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.utils.CirceOps.* -sealed trait LoadedConfigDTO { - def raw: String -} +final case class LoadedConfigDTO(raw: String) object LoadedConfigDTO { - implicit val codec: Codec[LoadedConfigDTO] = codecWithTypeDiscriminator( - encode = { - case dto: FILE_CONFIG => - derivedEncoderWithType[FILE_CONFIG]("FILE_CONFIG")(dto) - case dto: FORCED_FILE_CONFIG => - derivedEncoderWithType[FORCED_FILE_CONFIG]("FORCED_FILE_CONFIG")(dto) - case dto: INDEX_CONFIG => - derivedEncoderWithType[INDEX_CONFIG]("INDEX_CONFIG")(dto) - }, - decoders = Map( - "FILE_CONFIG" -> derivedDecoderOfSubtype[LoadedConfigDTO, FILE_CONFIG], - "FORCED_FILE_CONFIG" -> derivedDecoderOfSubtype[LoadedConfigDTO, FORCED_FILE_CONFIG], - "INDEX_CONFIG" -> derivedDecoderOfSubtype[LoadedConfigDTO, INDEX_CONFIG], - ) - ) - def create(o: LoadedRorConfig[String]): LoadedConfigDTO = o match { - case LoadedRorConfig.FileConfig(value) => FILE_CONFIG(value) - case LoadedRorConfig.ForcedFileConfig(value) => FORCED_FILE_CONFIG(value) - case LoadedRorConfig.IndexConfig(indexName, value) => INDEX_CONFIG(indexName.index.name.value, value) - } - final case class FILE_CONFIG(raw: String) extends LoadedConfigDTO - final case class FORCED_FILE_CONFIG(raw: String) extends LoadedConfigDTO - final case class INDEX_CONFIG(indexName: String, raw: String) extends LoadedConfigDTO + def create(o: LoadedRorConfig[String]): LoadedConfigDTO = LoadedConfigDTO(o.value) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala index fb55f6224d..a13d1d0fa7 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala @@ -17,30 +17,10 @@ package tech.beshu.ror.configuration import cats.Functor -import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} package object loader { - implicit class LoadedConfigOps[A](fa: LoadedRorConfig[A]) { - lazy val value: A = fa match { - case FileConfig(value) => value - case ForcedFileConfig(value) => value - case IndexConfig(_, value) => value - } - } - - implicit class LoadedTestConfigOps[A](fa: LoadedTestRorConfig[A]) { - lazy val value: A = fa match { - case LoadedTestRorConfig.IndexConfig(_, value) => value - case LoadedTestRorConfig.FallbackConfig(value) => value - } - } - implicit val functorLoadedConfig: Functor[LoadedRorConfig] = new Functor[LoadedRorConfig] { - override def map[A, B](fa: LoadedRorConfig[A])(f: A => B): LoadedRorConfig[B] = fa match { - case FileConfig(value) => FileConfig(f(value)) - case ForcedFileConfig(value) => ForcedFileConfig(f(value)) - case IndexConfig(indexName, value) => IndexConfig(indexName, f(value)) - } + override def map[A, B](fa: LoadedRorConfig[A])(f: A => B): LoadedRorConfig[B] = LoadedRorConfig(f(fa.value)) } } From f9f9a5a7cb3bc791415a3ddebbb50db25587805e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 2 Jul 2025 13:49:06 +0200 Subject: [PATCH 006/103] wip --- .../scala/tech/beshu/ror/SystemContext.scala | 8 +- .../scala/tech/beshu/ror/api/ConfigApi.scala | 13 ++-- .../tech/beshu/ror/api/TestConfigApi.scala | 9 +-- .../tech/beshu/ror/boot/ReadonlyRest.scala | 29 ++++--- .../tech/beshu/ror/boot/RorInstance.scala | 33 ++++---- .../beshu/ror/configuration/EsConfig.scala | 18 ++++- .../ror/configuration/RawRorConfig.scala | 55 +------------ .../RawRorConfigYamlParser.scala | 78 +++++++++++++++++++ ...igLoading.scala => RorConfigLoading.scala} | 33 ++++---- ...ading.scala => TestRorConfigLoading.scala} | 20 +++-- .../YamlFileBasedConfigLoader.scala | 6 +- .../index/BaseIndexConfigManager.scala | 7 +- .../index/IndexConfigManager.scala | 15 ++-- .../index/IndexTestConfigManager.scala | 15 ++-- ...Loader.scala => FileRorConfigLoader.scala} | 38 +++++---- .../loader/LoadRawRorConfig.scala | 44 ++++------- .../loader/LoadRawTestRorConfig.scala | 36 ++++----- ...nfigLoader.scala => RorConfigLoader.scala} | 23 +++--- ...cala => RorConfigLoadingInterpreter.scala} | 46 +++++------ ... => TestRorConfigLoadingInterpreter.scala} | 28 +++---- .../RawRorConfigLoadingAction.scala | 19 ++--- .../beshu/ror/utils/yaml/YamlKeyDecoder.scala | 10 ++- .../{RorYamlParser.scala => YamlParser.scala} | 4 +- .../indices/IndicesRuleLocalIndexTests.scala | 39 +++++----- .../configuration/LoadRawRorConfigTest.scala | 10 +-- ...=> YamlFileBasedRorConfigLoaderTest.scala} | 2 +- .../ror/unit/utils/RorYamlParserTests.scala | 6 +- .../tech/beshu/ror/utils/TestsUtils.scala | 4 +- 28 files changed, 330 insertions(+), 318 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala rename core/src/main/scala/tech/beshu/ror/configuration/{ConfigLoading.scala => RorConfigLoading.scala} (58%) rename core/src/main/scala/tech/beshu/ror/configuration/{TestConfigLoading.scala => TestRorConfigLoading.scala} (54%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{FileConfigLoader.scala => FileRorConfigLoader.scala} (50%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{ConfigLoader.scala => RorConfigLoader.scala} (63%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{ConfigLoadingInterpreter.scala => RorConfigLoadingInterpreter.scala} (69%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{TestConfigLoadingInterpreter.scala => TestRorConfigLoadingInterpreter.scala} (72%) rename core/src/main/scala/tech/beshu/ror/utils/yaml/{RorYamlParser.scala => YamlParser.scala} (91%) rename core/src/test/scala/tech/beshu/ror/unit/configuration/{YamlFileBasedConfigLoaderTest.scala => YamlFileBasedRorConfigLoaderTest.scala} (96%) diff --git a/core/src/main/scala/tech/beshu/ror/SystemContext.scala b/core/src/main/scala/tech/beshu/ror/SystemContext.scala index a85ed97c54..9b0b537342 100644 --- a/core/src/main/scala/tech/beshu/ror/SystemContext.scala +++ b/core/src/main/scala/tech/beshu/ror/SystemContext.scala @@ -18,10 +18,8 @@ package tech.beshu.ror import tech.beshu.ror.accesscontrol.blocks.variables.transformation.SupportedVariablesFunctions import tech.beshu.ror.accesscontrol.matchers.{RandomBasedUniqueIdentifierGenerator, UniqueIdentifierGenerator} -import tech.beshu.ror.configuration.RorProperties import tech.beshu.ror.providers.* import tech.beshu.ror.utils.js.{JsCompiler, MozillaJsCompiler} -import tech.beshu.ror.utils.yaml.RorYamlParser import java.time.Clock @@ -31,11 +29,7 @@ final class SystemContext(val clock: Clock = Clock.systemUTC(), val uniqueIdentifierGenerator: UniqueIdentifierGenerator = RandomBasedUniqueIdentifierGenerator, val uuidProvider: UuidProvider = JavaUuidProvider, val jsCompiler: JsCompiler = MozillaJsCompiler, - val variablesFunctions: SupportedVariablesFunctions = SupportedVariablesFunctions.default) { - - val yamlParser: RorYamlParser = new RorYamlParser(RorProperties.rorSettingsMaxSize(propertiesProvider)) -} - + val variablesFunctions: SupportedVariablesFunctions = SupportedVariablesFunctions.default) object SystemContext { val default: SystemContext = new SystemContext() diff --git a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala index 5484b1c126..b0f59098a3 100644 --- a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala @@ -22,7 +22,6 @@ import cats.implicits.* import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.api.ConfigApi.* import tech.beshu.ror.api.ConfigApi.ConfigRequest.Type @@ -30,18 +29,18 @@ import tech.beshu.ror.api.ConfigApi.ConfigResponse.* import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigReloadError, RawConfigReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} import tech.beshu.ror.configuration.index.IndexConfigError.IndexConfigNotExist import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.SpecializedError -import tech.beshu.ror.configuration.loader.FileConfigLoader +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.SpecializedError +import tech.beshu.ror.configuration.loader.FileRorConfigLoader import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class ConfigApi(rorInstance: RorInstance, + rawRorConfigYamlParser: RawRorConfigYamlParser, indexConfigManager: IndexConfigManager, - fileConfigLoader: FileConfigLoader, + fileConfigLoader: FileRorConfigLoader, rorConfigurationIndex: RorConfigurationIndex) - (implicit val systemContext: SystemContext) extends Logging { import ConfigApi.Utils.* @@ -116,7 +115,7 @@ class ConfigApi(rorInstance: RorInstance, } private def rorConfigFrom(configString: String): EitherT[Task, ConfigResponse, RawRorConfig] = EitherT { - RawRorConfig + rawRorConfigYamlParser .fromString(configString) .map(_.left.map(error => UpdateIndexConfig.Failure(error.show))) } diff --git a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala index f548c9ea95..cb8cc4ac6b 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala @@ -20,7 +20,6 @@ import cats.data.EitherT import cats.implicits.* import io.circe.Decoder import monix.eval.Task -import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning import tech.beshu.ror.accesscontrol.domain.{LoggedUser, RequestId} import tech.beshu.ror.api.TestConfigApi.TestConfigRequest.Type @@ -29,7 +28,7 @@ import tech.beshu.ror.api.TestConfigApi.{TestConfigRequest, TestConfigResponse} import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, RawConfigReloadError, TestConfig} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* @@ -38,8 +37,8 @@ import java.time.Instant import scala.concurrent.duration.* import scala.util.Try -class TestConfigApi(rorInstance: RorInstance) - (implicit systemContext: SystemContext) { +class TestConfigApi(rorInstance: RorInstance, + rawRorConfigYamlParser: RawRorConfigYamlParser) { import tech.beshu.ror.api.TestConfigApi.Utils.* import tech.beshu.ror.api.TestConfigApi.Utils.decoders.* @@ -73,7 +72,7 @@ class TestConfigApi(rorInstance: RorInstance) } private def rorTestConfig(configString: String): EitherT[Task, TestConfigResponse, RawRorConfig] = EitherT { - RawRorConfig + rawRorConfigYamlParser .fromString(configString) .map(_.left.map(error => TestConfigResponse.UpdateTestConfig.FailedResponse(error.show))) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index f15ad2f3a6..9b1399bf90 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,9 +34,9 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.configuration.ConfigLoading.{ErrorOr, LoadRorConfig} +import tech.beshu.ror.configuration.RorConfigLoading.{ErrorOr, LoadRorConfig} import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.TestConfigLoading.* +import tech.beshu.ror.configuration.TestRorConfigLoading.* import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} @@ -46,14 +46,16 @@ import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant class ReadonlyRest(coreFactory: CoreFactory, + indexContentService: IndexJsonContentService, auditSinkServiceCreator: AuditSinkServiceCreator, - val indexConfigManager: IndexConfigManager, - val indexTestConfigManager: IndexTestConfigManager, - val authServicesMocksProvider: MutableMocksProviderWithCachePerRequest, val esEnv: EsEnv) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { + private [boot] val indexConfigManager: IndexConfigManager = new IndexConfigManager(indexContentService, ???) + private [boot] val indexTestConfigManager: IndexTestConfigManager = new IndexTestConfigManager(indexContentService, ???) + private [boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) + def start(): Task[Either[StartingFailure, RorInstance]] = { (for { esConfig <- loadEsConfig() @@ -64,7 +66,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadEsConfig() = { - val action = ConfigLoading.loadEsConfig(esEnv) + val action = RorConfigLoading.loadEsConfig(esEnv) runStartingFailureProgram(action) } @@ -100,7 +102,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def runStartingFailureProgram[A](action: LoadRorConfig[ErrorOr[A]]) = { - val compiler = ConfigLoadingInterpreter.create(indexConfigManager) + val compiler = RorConfigLoadingInterpreter.create(indexConfigManager) EitherT(action.foldMap(compiler)) .leftMap(toStartingFailure) } @@ -127,7 +129,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def runTestProgram(action: LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]): Task[LoadedTestRorConfig[TestRorConfig]] = { - val compiler = TestConfigLoadingInterpreter.create(indexTestConfigManager) + val compiler = TestRorConfigLoadingInterpreter.create(indexTestConfigManager) EitherT(action.foldMap(compiler)) .leftMap { case LoadedTestRorConfig.IndexParsingError(message) => @@ -200,12 +202,13 @@ class ReadonlyRest(coreFactory: CoreFactory, loadedConfig: LoadedRorConfig[RawRorConfig]) = { EitherT.right[StartingFailure] { val rorSettingsFile = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile + val rorSettingsMaxSize = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsMaxSize val rorConfigIndex = esConfig.rorEsLevelSettings.rorConfigIndex esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, rorSettingsFile, rorConfigIndex) + RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, settings.refreshInterval, rorSettingsFile, rorConfigIndex) + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) } } } @@ -337,10 +340,6 @@ object ReadonlyRest { env: EsEnv) (implicit scheduler: Scheduler, systemContext: SystemContext): ReadonlyRest = { - val indexConfigManager: IndexConfigManager = new IndexConfigManager(indexContentService) - val indexTestConfigManager: IndexTestConfigManager = new IndexTestConfigManager(indexContentService) - val mocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) - - new ReadonlyRest(coreFactory, auditSinkServiceCreator, indexConfigManager, indexTestConfigManager, mocksProvider, env) + new ReadonlyRest(coreFactory, indexContentService, auditSinkServiceCreator, env) } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 8307b88439..b0e622aa34 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -25,6 +25,7 @@ import monix.catnap.Semaphore import monix.eval.Task import monix.execution.{Cancelable, Scheduler} import org.apache.logging.log4j.scala.Logging +import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} @@ -32,9 +33,9 @@ import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} import tech.beshu.ror.boot.engines.{Engines, MainConfigBasedReloadableEngine, TestConfigBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval import tech.beshu.ror.configuration.index.{IndexConfigError, SavingIndexConfigError} -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.FileConfigLoader -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error +import tech.beshu.ror.configuration.loader.FileRorConfigLoader +import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser, RorConfig} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -47,7 +48,8 @@ class RorInstance private(boot: ReadonlyRest, initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], rorSettingsIndex: RorConfigurationIndex, - rorSettingsFile: File) + rorSettingsFile: File, + rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -77,18 +79,19 @@ class RorInstance private(boot: ReadonlyRest, rorSettingsIndex ) + private val rarRorConfigYamlParser = new RawRorConfigYamlParser(rorSettingsMaxSize) + private val configRestApi = new ConfigApi( rorInstance = this, + rarRorConfigYamlParser, boot.indexConfigManager, - new FileConfigLoader(rorSettingsFile), + new FileRorConfigLoader(rorSettingsFile, rarRorConfigYamlParser), rorSettingsIndex ) - private val authMockRestApi = new AuthMockApi( - rorInstance = this - ) + private val authMockRestApi = new AuthMockApi(rorInstance = this) - private val testConfigRestApi = new TestConfigApi(this) + private val testConfigRestApi = new TestConfigApi(rorInstance = this, rarRorConfigYamlParser) def engines: Option[Engines] = aMainConfigEngine.engine.map(Engines(_, anTestConfigEngine.engine)) @@ -231,7 +234,7 @@ object RorInstance { sealed trait IndexConfigReloadError object IndexConfigReloadError { - final case class LoadingConfigError(underlying: ConfigLoaderError[IndexConfigError]) extends IndexConfigReloadError + final case class LoadingConfigError(underlying: Error[IndexConfigError]) extends IndexConfigReloadError final case class ReloadError(underlying: RawConfigReloadError) extends IndexConfigReloadError } @@ -269,20 +272,22 @@ object RorInstance { testEngine: ReadonlyRest.TestEngine, refreshInterval: RefreshInterval, rorSettingsFile: File, + rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) + create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, rorSettingsFile: File, + rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsIndex) + create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) } private def create(boot: ReadonlyRest, @@ -290,6 +295,7 @@ object RorInstance { engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, rorSettingsFile: File, + rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) = { @@ -304,7 +310,8 @@ object RorInstance { initialTestEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, rorSettingsIndex = rorSettingsIndex, - rorSettingsFile = rorSettingsFile + rorSettingsFile = rorSettingsFile, + rorSettingsMaxSize = rorSettingsMaxSize ) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala index d8d8702977..ae2bb11bc1 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala @@ -131,10 +131,15 @@ object EsConfig { extends LoadingRorCoreStrategy } - implicit class RorSettingsFileFromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { - def rorSettingsFile: File = strategy match + implicit class FromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { + def rorSettingsFile: File = strategy match { case ForceLoadingFromFile(settings) => settings.rorSettingsFile case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings.rorSettingsFile + } + def rorSettingsMaxSize: Information = strategy match { + case ForceLoadingFromFile(settings) => settings.settingsMaxSize + case LoadFromIndexWithFileFallback(settings, _) => settings.settingsMaxSize + } } final case class LoadFromFileSettings(rorSettingsFile: File, @@ -169,8 +174,8 @@ object EsConfig { alternativePath = NonEmptyList.of("readonlyrest", "force_load_from_file"), // for a sake of backward compatibility default = false ) map { - case true => ??? - case false => ??? + case true => LoadingRorCoreStrategy.ForceLoadingFromFile(???) + case false => LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(???, ???) } } @@ -203,6 +208,11 @@ object EsConfig { (booleanDecoder or stringDecoder) map XpackSettings.apply } } + +// private implicit val loadFromFileSettingsDecoder: Decoder[LoadFromFileSettings] = { +// //YamlKeyDecoder[String](path = NonEmptyList.of("readonlyrest", "settings", "file", "path")) +// ??? +// } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala index af49813a03..aa6e83ba3c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala @@ -16,61 +16,10 @@ */ package tech.beshu.ror.configuration -import better.files.File -import cats.effect.Resource -import cats.{Eq, Show} -import io.circe.{Json, ParsingFailure} -import monix.eval.Task -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RawRorConfig.ParsingRorConfigError.{InvalidContent, MoreThanOneRorSection, NoRorSection} -import tech.beshu.ror.implicits.* - -import java.io.StringReader +import cats.Eq +import io.circe.Json final case class RawRorConfig(configJson: Json, raw: String) - object RawRorConfig { - - def fromFile(file: File) - (implicit systemContext: SystemContext): Task[Either[ParsingRorConfigError, RawRorConfig]] = { - fromString(file.contentAsString) - } - - def fromString(content: String) - (implicit systemContext: SystemContext): Task[Either[ParsingRorConfigError, RawRorConfig]] = { - val contentResource = Resource.make(Task(new StringReader(content))) { reader => Task(reader.close()) } - contentResource.use { reader => Task { - handleParseResult(systemContext.yamlParser.parse(reader)) - .map(RawRorConfig(_, content)) - }} - } - - private def handleParseResult(result: Either[ParsingFailure, Json]) = { - result - .left.map(InvalidContent.apply) - .flatMap { json => validateRorJson(json) } - } - - private def validateRorJson(json: Json) = { - json \\ "readonlyrest" match { - case Nil => Left(NoRorSection) - case _ :: Nil => Right(json) - case _ => Left(MoreThanOneRorSection) - } - } - - sealed trait ParsingRorConfigError - object ParsingRorConfigError { - case object NoRorSection extends ParsingRorConfigError - case object MoreThanOneRorSection extends ParsingRorConfigError - final case class InvalidContent(throwable: Throwable) extends ParsingRorConfigError - - implicit val show: Show[ParsingRorConfigError] = Show.show { - case NoRorSection => "Cannot find any 'readonlyrest' section in settings" - case MoreThanOneRorSection => "Only one 'readonlyrest' section is required" - case InvalidContent(ex) => s"Settings content is malformed. Details: ${ex.getMessage.show}" - } - } - implicit val eq: Eq[RawRorConfig] = Eq.fromUniversalEquals } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala new file mode 100644 index 0000000000..5fde701494 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala @@ -0,0 +1,78 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.configuration + +import better.files.File +import cats.effect.Resource +import cats.Show +import io.circe.{Json, ParsingFailure} +import monix.eval.Task +import squants.information.Information +import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError +import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError.{InvalidContent, MoreThanOneRorSection, NoRorSection} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.yaml.YamlParser + +import java.io.StringReader + +class RawRorConfigYamlParser(maxSize: Information) { + + private val yamlParser: YamlParser = new YamlParser(Some(maxSize)) + + def fromFile(file: File): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + fromString(file.contentAsString) + } + + def fromString(content: String): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + val contentResource = Resource.make(Task(new StringReader(content))) { reader => Task(reader.close()) } + contentResource.use { reader => + Task { + handleParseResult(yamlParser.parse(reader)) + .map(RawRorConfig(_, content)) + } + } + } + + private def handleParseResult(result: Either[ParsingFailure, Json]) = { + result + .left.map(InvalidContent.apply) + .flatMap { json => validateRorJson(json) } + } + + private def validateRorJson(json: Json) = { + json \\ "readonlyrest" match { + case Nil => Left(NoRorSection) + case _ :: Nil => Right(json) + case _ => Left(MoreThanOneRorSection) + } + } +} +object RawRorConfigYamlParser { + + sealed trait ParsingRorConfigError + object ParsingRorConfigError { + case object NoRorSection extends ParsingRorConfigError + case object MoreThanOneRorSection extends ParsingRorConfigError + final case class InvalidContent(throwable: Throwable) extends ParsingRorConfigError + + implicit val show: Show[ParsingRorConfigError] = Show.show { + case NoRorSection => "Cannot find any 'readonlyrest' section in settings" + case MoreThanOneRorSection => "Only one 'readonlyrest' section is required" + case InvalidContent(ex) => s"Settings content is malformed. Details: ${ex.getMessage.show}" + } + } +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala similarity index 58% rename from core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala rename to core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala index 13cfeb28d5..a18d6009b0 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/ConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala @@ -17,40 +17,37 @@ package tech.beshu.ror.configuration import cats.free.Free -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.loader.LoadedRorConfig import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration -object ConfigLoading { +object RorConfigLoading { type ErrorOr[A] = LoadedRorConfig.Error Either A type IndexErrorOr[A] = LoadedRorConfig.LoadingIndexError Either A - type LoadRorConfig[A] = Free[LoadConfigAction, A] + type LoadRorConfig[A] = Free[LoadRorConfigAction, A] - sealed trait LoadConfigAction[A] - object LoadConfigAction { + sealed trait LoadRorConfigAction[A] + object LoadRorConfigAction { final case class LoadEsConfig(env: EsEnv) - extends LoadConfigAction[ErrorOr[EsConfig]] + extends LoadRorConfigAction[ErrorOr[EsConfig]] final case class ForceLoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] + extends LoadRorConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] final case class LoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] - final case class LoadRorConfigFromIndex(index: RorConfigurationIndex, loadingDelay: NonNegativeFiniteDuration) - extends LoadConfigAction[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] + extends LoadRorConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] + final case class LoadRorConfigFromIndex(settings: LoadFromIndexSettings) + extends LoadRorConfigAction[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] } - def loadRorConfigFromIndex(index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration): LoadRorConfig[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadConfigAction.LoadRorConfigFromIndex(index, loadingDelay)) + def loadRorConfigFromIndex(settings: LoadFromIndexSettings): LoadRorConfig[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] = + Free.liftF(LoadRorConfigAction.LoadRorConfigFromIndex(settings)) def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadConfigAction.LoadRorConfigFromFile(settings)) + Free.liftF(LoadRorConfigAction.LoadRorConfigFromFile(settings)) def loadEsConfig(env: EsEnv): LoadRorConfig[ErrorOr[EsConfig]] = - Free.liftF(LoadConfigAction.LoadEsConfig(env)) + Free.liftF(LoadRorConfigAction.LoadEsConfig(env)) def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadConfigAction.ForceLoadRorConfigFromFile(settings)) + Free.liftF(LoadRorConfigAction.ForceLoadRorConfigFromFile(settings)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala similarity index 54% rename from core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala rename to core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala index aa01b72c5e..43da273ed9 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala @@ -17,22 +17,20 @@ package tech.beshu.ror.configuration import cats.free.Free -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings import tech.beshu.ror.configuration.loader.LoadedTestRorConfig -import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration -object TestConfigLoading { +object TestRorConfigLoading { type IndexErrorOr[A] = LoadedTestRorConfig.LoadingIndexError Either A - type LoadTestRorConfig[A] = Free[LoadTestConfigAction, A] + type LoadTestRorConfig[A] = Free[LoadRorTestConfigAction, A] - sealed trait LoadTestConfigAction[A] - object LoadTestConfigAction { - final case class LoadRorConfigFromIndex(index: RorConfigurationIndex, loadingDelay: NonNegativeFiniteDuration) - extends LoadTestConfigAction[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] + sealed trait LoadRorTestConfigAction[A] + object LoadRorTestConfigAction { + final case class LoadTestRorConfigFromIndex(settings: LoadFromIndexSettings) + extends LoadRorTestConfigAction[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] } - def loadRorConfigFromIndex(index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = - Free.liftF(LoadTestConfigAction.LoadRorConfigFromIndex(index, loadingDelay)) + def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = + Free.liftF(LoadRorTestConfigAction.LoadTestRorConfigFromIndex(settings)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala index b4821418c2..f4f67f892b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala @@ -22,11 +22,14 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.factory.JsonConfigStaticVariableResolver import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.yaml.YamlParser import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson final class YamlFileBasedConfigLoader(file: File) (implicit systemContext: SystemContext) { + private val yamlParser: YamlParser = new YamlParser() + private val jsonConfigResolver = new JsonConfigStaticVariableResolver( systemContext.envVarsProvider, TransformationCompiler.withoutAliases(systemContext.variablesFunctions) @@ -43,8 +46,7 @@ final class YamlFileBasedConfigLoader(file: File) private lazy val loadedConfigJson: Either[MalformedSettings, Json] = { file.fileReader { reader => - systemContext - .yamlParser + yamlParser .parse(reader) .left.map(e => MalformedSettings(s"Cannot parse file ${file.pathAsString.show} content. Cause: ${e.message.show}")) .flatMap { json => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala index 35d271a61c..3566deb989 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala @@ -18,12 +18,13 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.SpecializedError +import tech.beshu.ror.configuration.loader.RorConfigLoader +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.SpecializedError +// todo: it looks like this manager should extend RorConfigLoader trait BaseIndexConfigManager[A] { - def load(indexName: RorConfigurationIndex): Task[Either[ConfigLoaderError[IndexConfigError], A]] + def load(indexName: RorConfigurationIndex): Task[Either[RorConfigLoader.Error[IndexConfigError], A]] def save(config: A, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexConfigError, Unit]] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala index af780967b2..ae7523d819 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala @@ -18,21 +18,20 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, IndexConfigUnknownStructure} -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.ParsingError +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.ParsingError import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -final class IndexConfigManager(indexJsonContentService: IndexJsonContentService) - (implicit systemContext: SystemContext) +final class IndexConfigManager(indexJsonContentService: IndexJsonContentService, + rarRorConfigYamlParser: RawRorConfigYamlParser) extends BaseIndexConfigManager[RawRorConfig] with Logging { - override def load(indexName: RorConfigurationIndex): Task[Either[ConfigLoaderError[IndexConfigError], RawRorConfig]] = { + override def load(indexName: RorConfigurationIndex): Task[Either[Error[IndexConfigError], RawRorConfig]] = { indexJsonContentService .sourceOf(indexName.index, Config.rorSettingsIndexConst.id) .flatMap { @@ -40,7 +39,7 @@ final class IndexConfigManager(indexJsonContentService: IndexJsonContentService) source .find(_._1 == Config.rorSettingsIndexConst.settingsKey) .map { case (_, rorYamlString) => - RawRorConfig + rarRorConfigYamlParser .fromString(rorYamlString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala index d882dcb06b..483af8b445 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala @@ -23,7 +23,6 @@ import io.circe.syntax.EncoderOps import io.circe.{Codec, Decoder, Encoder} import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks @@ -36,9 +35,9 @@ import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorConfigurationIn import tech.beshu.ror.configuration.TestRorConfig.Present import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, IndexConfigUnknownStructure} import tech.beshu.ror.configuration.index.IndexTestConfigManager.Const -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{RawRorConfig, TestRorConfig} +import tech.beshu.ror.configuration.loader.RorConfigLoader +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.{RawRorConfigYamlParser, TestRorConfig} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} import tech.beshu.ror.syntax.* @@ -50,12 +49,12 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentService) - (implicit systemContext: SystemContext) +final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentService, + rarRorConfigYamlParser: RawRorConfigYamlParser) extends BaseIndexConfigManager[TestRorConfig] with Logging { - type Error = ConfigLoaderError[IndexConfigError] + type Error = RorConfigLoader.Error[IndexConfigError] override def load(indexName: RorConfigurationIndex): Task[Either[Error, TestRorConfig]] = { indexJsonContentService @@ -94,7 +93,7 @@ final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentServ rawRorConfigString <- getConfigProperty(config, Const.properties.settings) authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) rawRorConfig <- EitherT { - RawRorConfig + rarRorConfigYamlParser .fromString(rawRorConfigString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala similarity index 50% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala index 7eb14b4c47..a0a4a6b1bf 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala @@ -20,18 +20,16 @@ import better.files.File import cats.Show import cats.data.EitherT import monix.eval.Task -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError -import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError.FileNotExist - -class FileConfigLoader(rorSettingsFile: File) - (implicit systemContext: SystemContext) - extends ConfigLoader[FileConfigError] { - - override def load(): Task[Either[ConfigLoaderError[FileConfigError], RawRorConfig]] = { +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.FileRorConfigLoader.Error.FileNotExist +import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} + +class FileRorConfigLoader(rorSettingsFile: File, + rarRorConfigYamlParser: RawRorConfigYamlParser) + extends RorConfigLoader[FileRorConfigLoader.Error] { + + override def load(): Task[Either[Error[FileRorConfigLoader.Error], RawRorConfig]] = { val file = rorSettingsFile (for { _ <- checkIfFileExist(file) @@ -39,21 +37,21 @@ class FileConfigLoader(rorSettingsFile: File) } yield config).value } - private def checkIfFileExist(file: File): EitherT[Task, ConfigLoaderError[FileConfigError], File] = + private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorConfigLoader.Error], File] = EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) - private def loadConfigFromFile(file: File): EitherT[Task, ConfigLoaderError[FileConfigError], RawRorConfig] = { - EitherT(RawRorConfig.fromFile(file).map(_.left.map(ParsingError.apply))) + private def loadConfigFromFile(file: File): EitherT[Task, Error[FileRorConfigLoader.Error], RawRorConfig] = { + EitherT(rarRorConfigYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) } } -object FileConfigLoader { +object FileRorConfigLoader { - sealed trait FileConfigError - object FileConfigError { - final case class FileNotExist(file: File) extends FileConfigError + sealed trait Error + object Error { + final case class FileNotExist(file: File) extends Error - implicit val show: Show[FileConfigError] = Show.show { + implicit val show: Show[Error] = Show.show { case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index 0a5b1a7807..46c6a80fd1 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -17,12 +17,10 @@ package tech.beshu.ror.configuration.loader import cats.free.Free -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.ConfigLoading.* import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} -import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, RefinedDurationOps} +import tech.beshu.ror.configuration.RorConfigLoading.* +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import scala.concurrent.duration.DurationInt import scala.language.postfixOps @@ -34,10 +32,7 @@ object LoadRawRorConfig { def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, fallbackFileLoadingSettings: LoadFromFileSettings): LoadRorConfig[LoadResult] = { attemptLoadingConfigFromIndex( - index = indexLoadingSettings.rorConfigIndex, - currentDelay = indexLoadingSettings.loadingDelay.value, - attemptsCount = indexLoadingSettings.loadingAttemptsCount, - attemptsInterval = indexLoadingSettings.loadingAttemptsInterval, + settings = indexLoadingSettings, fallback = loadRorConfigFromFile(fallbackFileLoadingSettings) ) } @@ -48,48 +43,43 @@ object LoadRawRorConfig { } yield loadedConfig } - def loadFromIndex(configurationIndex: RorConfigurationIndex): LoadRorConfig[LoadResult] = { + def loadFromIndex(settings: LoadFromIndexSettings): LoadRorConfig[LoadResult] = { for { - result <- loadRorConfigFromIndex(configurationIndex, loadingDelay = (0 seconds).toRefinedNonNegativeUnsafe) + // todo: is the copy ok? + result <- loadRorConfigFromIndex(settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds))) rawRorConfig <- result match { case Left(LoadedRorConfig.IndexNotExist) => - Free.pure[LoadConfigAction, LoadResult](Left(LoadedRorConfig.IndexNotExist)) + Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexNotExist)) case Left(LoadedRorConfig.IndexUnknownStructure) => - Free.pure[LoadConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) + Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) case Left(error@LoadedRorConfig.IndexParsingError(_)) => - Free.pure[LoadConfigAction, LoadResult](Left(error)) + Free.pure[LoadRorConfigAction, LoadResult](Left(error)) case Right(value) => - Free.pure[LoadConfigAction, LoadResult](Right(value)) + Free.pure[LoadRorConfigAction, LoadResult](Right(value)) } } yield rawRorConfig } - private def attemptLoadingConfigFromIndex(index: RorConfigurationIndex, - currentDelay: NonNegativeFiniteDuration, - attemptsCount: LoadingAttemptsCount, - attemptsInterval: LoadingAttemptsInterval, + private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, fallback: LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]]): LoadRorConfig[LoadResult] = { - attemptsCount.value.value match { + settings.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => for { - result <- loadRorConfigFromIndex(index, loadingDelay = currentDelay) + result <- loadRorConfigFromIndex(settings) rawRorConfig <- result match { case Left(LoadedRorConfig.IndexNotExist) => Free.defer(attemptLoadingConfigFromIndex( - index = index, - currentDelay = attemptsInterval.value, - attemptsCount = LoadingAttemptsCount.unsafeFrom(attemptsCount - 1), - attemptsInterval = attemptsInterval, + settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), fallback = fallback )) case Left(LoadedRorConfig.IndexUnknownStructure) => - Free.pure[LoadConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) + Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) case Left(error@LoadedRorConfig.IndexParsingError(_)) => - Free.pure[LoadConfigAction, LoadResult](Left(error)) + Free.pure[LoadRorConfigAction, LoadResult](Left(error)) case Right(value) => - Free.pure[LoadConfigAction, LoadResult](Right(value)) + Free.pure[LoadRorConfigAction, LoadResult](Right(value)) } } yield rawRorConfig } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala index 39190f2b35..64f8257fe8 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala @@ -17,54 +17,46 @@ package tech.beshu.ror.configuration.loader import cats.free.Free -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} -import tech.beshu.ror.configuration.TestConfigLoading.* +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.TestRorConfig -import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration +import tech.beshu.ror.configuration.TestRorConfigLoading.* + +import scala.concurrent.duration.DurationInt +import scala.language.postfixOps object LoadRawTestRorConfig { def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, fallbackConfig: TestRorConfig): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = { attemptLoadingConfigFromIndex( - index = indexLoadingSettings.rorConfigIndex, - currentDelay = indexLoadingSettings.loadingDelay.value, - attemptsCount = indexLoadingSettings.loadingAttemptsCount, - attemptsInterval = indexLoadingSettings.loadingAttemptsInterval, + settings = indexLoadingSettings, fallback = fallbackConfig ) } - private def attemptLoadingConfigFromIndex(index: RorConfigurationIndex, - currentDelay: NonNegativeFiniteDuration, - attemptsCount: LoadingAttemptsCount, - attemptsInterval: LoadingAttemptsInterval, + private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, fallback: TestRorConfig): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = { - attemptsCount.value.value match { + settings.loadingAttemptsCount.value.value match { case 0 => - Free.pure[LoadTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]( + Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]( Right(LoadedTestRorConfig[TestRorConfig](fallback)) ) case attemptsCount => for { - result <- loadRorConfigFromIndex(index, loadingDelay = currentDelay) + result <- loadTestRorConfigFromIndex(settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds))) rawRorConfig <- result match { case Left(LoadedTestRorConfig.IndexNotExist) => Free.defer(attemptLoadingConfigFromIndex( - index = index, - currentDelay = attemptsInterval.value, - attemptsCount = LoadingAttemptsCount.unsafeFrom(attemptsCount - 1), - attemptsInterval = attemptsInterval, + settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), fallback = fallback )) case Left(error@LoadedTestRorConfig.IndexUnknownStructure) => - Free.pure[LoadTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) + Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) case Left(error@LoadedTestRorConfig.IndexParsingError(_)) => - Free.pure[LoadTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) + Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) case Right(value) => - Free.pure[LoadTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Right(value)) + Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Right(value)) } } yield rawRorConfig } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala similarity index 63% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala index 50140ff067..7759bf8e9c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala @@ -17,27 +17,24 @@ package tech.beshu.ror.configuration.loader import cats.Show -import cats.implicits.* import monix.eval.Task import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.RawRorConfig.ParsingRorConfigError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError +import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError -trait ConfigLoader[SPECIALIZED_ERROR] { - - def load(): Task[Either[ConfigLoaderError[SPECIALIZED_ERROR], RawRorConfig]] +trait RorConfigLoader[SPECIALIZED_ERROR] { + def load(): Task[Either[RorConfigLoader.Error[SPECIALIZED_ERROR], RawRorConfig]] } -object ConfigLoader { +object RorConfigLoader { - sealed trait ConfigLoaderError[+SPECIALIZED_ERROR] - object ConfigLoaderError { - final case class ParsingError(error: ParsingRorConfigError) extends ConfigLoaderError[Nothing] - final case class SpecializedError[ERROR](error: ERROR) extends ConfigLoaderError[ERROR] + sealed trait Error[+SPECIALIZED_ERROR] + object Error { + final case class ParsingError(error: ParsingRorConfigError) extends Error[Nothing] + final case class SpecializedError[ERROR](error: ERROR) extends Error[ERROR] - implicit def show[E: Show]: Show[ConfigLoaderError[E]] = Show.show { - case ParsingError(error) => Show[RawRorConfig.ParsingRorConfigError].show(error) + implicit def show[E: Show]: Show[Error[E]] = Show.show { + case ParsingError(error) => Show[ParsingRorConfigError].show(error) case SpecializedError(error) => Show[E].show(error) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala similarity index 69% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala index 109db32200..3b9c18dc23 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/ConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala @@ -22,24 +22,23 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.ConfigLoading.LoadConfigAction import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType +import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError.* +import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction +import tech.beshu.ror.configuration.RorProperties.LoadingDelay import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.FileConfigLoader.FileConfigError import tech.beshu.ror.configuration.loader.LoadedRorConfig.* -import tech.beshu.ror.configuration.{ConfigLoading, EsConfig} +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.{EsConfig, RawRorConfigYamlParser, RorConfigLoading} import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration -object ConfigLoadingInterpreter extends Logging { +object RorConfigLoadingInterpreter extends Logging { def create(indexConfigManager: IndexConfigManager) - (implicit systemContext: SystemContext): LoadConfigAction ~> Task = new (LoadConfigAction ~> Task) { - override def apply[A](fa: LoadConfigAction[A]): Task[A] = fa match { - case ConfigLoading.LoadConfigAction.LoadEsConfig(env) => + (implicit systemContext: SystemContext): LoadRorConfigAction ~> Task = new (LoadRorConfigAction ~> Task) { + override def apply[A](fa: LoadRorConfigAction[A]): Task[A] = fa match { + case RorConfigLoading.LoadRorConfigAction.LoadEsConfig(env) => logger.info(s"Loading Elasticsearch settings from file: ${env.elasticsearchConfig.show}") EsConfig .from(env) @@ -56,28 +55,31 @@ object ConfigLoadingInterpreter extends Logging { } ) }) - case ConfigLoading.LoadConfigAction.ForceLoadRorConfigFromFile(settings) => + case RorConfigLoading.LoadRorConfigAction.ForceLoadRorConfigFromFile(settings) => val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") - EitherT(new FileConfigLoader(rorSettingsFile).load()) + EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) .bimap(convertFileError, LoadedRorConfig.apply) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") error }.value - case ConfigLoading.LoadConfigAction.LoadRorConfigFromFile(settings) => + case RorConfigLoading.LoadRorConfigAction.LoadRorConfigFromFile(settings) => val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - EitherT(new FileConfigLoader(rorSettingsFile).load()) + EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) .bimap(convertFileError, LoadedRorConfig.apply) .leftMap { error => logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") error } .value - case ConfigLoading.LoadConfigAction.LoadRorConfigFromIndex(configIndex, inIndexLoadingDelay) => - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${configIndex.index.show}) ...") - loadFromIndex(indexConfigManager, configIndex, inIndexLoadingDelay) + case RorConfigLoading.LoadRorConfigAction.LoadRorConfigFromIndex(settings) => + val rorConfigIndex = settings.rorConfigIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") + loadFromIndex(indexConfigManager, rorConfigIndex, settings.loadingDelay) .map { rawRorConfig => logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") rawRorConfig @@ -103,24 +105,24 @@ object ConfigLoadingInterpreter extends Logging { private def loadFromIndex[A](indexConfigManager: IndexConfigManager, index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration) = { + loadingDelay: LoadingDelay) = { EitherT { indexConfigManager .load(index) - .delayExecution(loadingDelay.value) + .delayExecution(loadingDelay.value.value) } } - private def convertFileError(error: ConfigLoaderError[FileConfigError]): LoadedRorConfig.Error = { + private def convertFileError(error: RorConfigLoader.Error[FileRorConfigLoader.Error]): LoadedRorConfig.Error = { error match { case ParsingError(error) => val show = error.show LoadedRorConfig.FileParsingError(show) - case SpecializedError(FileConfigError.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) + case SpecializedError(FileRorConfigLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) } } - private def convertIndexError(error: ConfigLoaderError[IndexConfigError])= + private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError])= error match { case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedRorConfig.IndexNotExist diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala similarity index 72% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala index dddd71f990..e7850e7805 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala @@ -21,22 +21,22 @@ import cats.~> import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.TestConfigLoading.LoadTestConfigAction +import tech.beshu.ror.configuration.RorProperties.LoadingDelay +import tech.beshu.ror.configuration.TestRorConfigLoading.LoadRorTestConfigAction import tech.beshu.ror.configuration.index.{IndexConfigError, IndexTestConfigManager} -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError -import tech.beshu.ror.configuration.loader.ConfigLoader.ConfigLoaderError.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.* -import tech.beshu.ror.configuration.{TestConfigLoading, TestRorConfig} +import tech.beshu.ror.configuration.{TestRorConfig, TestRorConfigLoading} import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.DurationOps.NonNegativeFiniteDuration -object TestConfigLoadingInterpreter extends Logging { +object TestRorConfigLoadingInterpreter extends Logging { - def create(indexConfigManager: IndexTestConfigManager): LoadTestConfigAction ~> Task = new (LoadTestConfigAction ~> Task) { - override def apply[A](fa: LoadTestConfigAction[A]): Task[A] = fa match { - case TestConfigLoading.LoadTestConfigAction.LoadRorConfigFromIndex(configIndex, loadingDelay) => - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${configIndex.index.show}) ...") - loadFromIndex(indexConfigManager, configIndex, loadingDelay) + def create(indexConfigManager: IndexTestConfigManager): LoadRorTestConfigAction ~> Task = new (LoadRorTestConfigAction ~> Task) { + override def apply[A](fa: LoadRorTestConfigAction[A]): Task[A] = fa match { + case TestRorConfigLoading.LoadRorTestConfigAction.LoadTestRorConfigFromIndex(settings) => + val rorConfigIndex = settings.rorConfigIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") + loadFromIndex(indexConfigManager, rorConfigIndex, settings.loadingDelay) .map { testConfig => testConfig match { case TestRorConfig.Present(rawConfig, _, _) => @@ -67,15 +67,15 @@ object TestConfigLoadingInterpreter extends Logging { private def loadFromIndex(indexConfigManager: IndexTestConfigManager, index: RorConfigurationIndex, - loadingDelay: NonNegativeFiniteDuration) = { + loadingDelay: LoadingDelay) = { EitherT { indexConfigManager .load(index) - .delayExecution(loadingDelay.value) + .delayExecution(loadingDelay.value.value) } } - private def convertIndexError(error: ConfigLoaderError[IndexConfigError]): LoadedTestRorConfig.LoadingIndexError = + private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]): LoadedTestRorConfig.LoadingIndexError = error match { case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedTestRorConfig.IndexNotExist diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala index a8c4e8c95a..8f9c95e371 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala @@ -19,27 +19,28 @@ package tech.beshu.ror.configuration.loader.distributed import cats.data.EitherT import monix.eval.Task import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.ConfigLoading.LoadRorConfig +import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfig import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.IndexConfigManager -import tech.beshu.ror.configuration.loader.{ConfigLoadingInterpreter, LoadRawRorConfig, LoadedRorConfig} -import tech.beshu.ror.configuration.{ConfigLoading, RawRorConfig} -import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} +import tech.beshu.ror.configuration.loader.{RorConfigLoadingInterpreter, LoadRawRorConfig, LoadedRorConfig} +import tech.beshu.ror.configuration.{RorConfigLoading, RawRorConfig} +import tech.beshu.ror.es.EsEnv object RawRorConfigLoadingAction { - def loadFromIndex(env: EsEnv, indexJsonContentService: IndexJsonContentService) + // todo: IndexConfigManager or maybe not? + def loadFromIndex(env: EsEnv, indexConfigManager: IndexConfigManager) (implicit systemContext: SystemContext): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { - val compiler = ConfigLoadingInterpreter.create(new IndexConfigManager(indexJsonContentService)) + val compiler = RorConfigLoadingInterpreter.create(indexConfigManager) (for { - esConfig <- EitherT(ConfigLoading.loadEsConfig(env)) + esConfig <- EitherT(RorConfigLoading.loadEsConfig(env)) loadedConfig <- esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.leftT[LoadRorConfig, LoadedRorConfig[RawRorConfig]]( LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled("todo"): LoadedRorConfig.Error // todo: fixme ) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, _) => - EitherT(LoadRawRorConfig.loadFromIndex(esConfig.rorEsLevelSettings.rorConfigIndex)) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => + EitherT(LoadRawRorConfig.loadFromIndex(settings)) } } yield loadedConfig).value.foldMap(compiler) } diff --git a/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala index 0cc07b6b6f..6d6adc59d4 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlKeyDecoder.scala @@ -43,16 +43,20 @@ private class YamlKeyDecoder[A: Decoder](segments: NonEmptyList[String]) extends object YamlKeyDecoder { def apply[A: Decoder](path: NonEmptyList[String], default: A): Decoder[A] = { - new YamlKeyDecoder[A](path).map(_.getOrElse(default)) + apply(path).map(_.getOrElse(default)) } def apply[A: Decoder](path: NonEmptyList[String], alternativePath: NonEmptyList[String], default: A): Decoder[A] = { for { - decodedValue <- new YamlKeyDecoder[A](path) + decodedValue <- apply(path) alternativeDecodedValue <- decodedValue match { case Some(value) => Decoder.const[Option[A]](Some(value)) - case None => new YamlKeyDecoder[A](alternativePath) + case None => apply(alternativePath) } } yield alternativeDecodedValue.getOrElse(default) } + + def apply[A: Decoder](path: NonEmptyList[String]): Decoder[Option[A]] = { + new YamlKeyDecoder[A](path) + } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/utils/yaml/RorYamlParser.scala b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlParser.scala similarity index 91% rename from core/src/main/scala/tech/beshu/ror/utils/yaml/RorYamlParser.scala rename to core/src/main/scala/tech/beshu/ror/utils/yaml/YamlParser.scala index 78d6949321..5421b384b6 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/yaml/RorYamlParser.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/yaml/YamlParser.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.org.yaml.snakeyaml.LoaderOptions import java.io.{Reader, StringReader} -class RorYamlParser(maxSize: Information) { +class YamlParser(maxSize: Option[Information] = None) { def parse(yaml: Reader): Either[ParsingFailure, Json] = { tech.beshu.ror.utils.yaml.parser.parse(yaml, loaderOptions) @@ -39,7 +39,7 @@ class RorYamlParser(maxSize: Information) { private lazy val loaderOptions: LoaderOptions = { val options = new LoaderOptions - options.setCodePointLimit(maxSize.toBytes.toInt) + maxSize.foreach { m => options.setCodePointLimit(m.toBytes.toInt) } options } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/indices/IndicesRuleLocalIndexTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/indices/IndicesRuleLocalIndexTests.scala index 7625e366ed..4cf380702f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/indices/IndicesRuleLocalIndexTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/indices/IndicesRuleLocalIndexTests.scala @@ -18,7 +18,6 @@ package tech.beshu.ror.unit.acl.blocks.rules.indices import cats.data.NonEmptySet import monix.eval.Task -import tech.beshu.ror.accesscontrol.orders.requestedIndexOrder import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.domain.KibanaIndexName import tech.beshu.ror.accesscontrol.orders.custerIndexNameOrder @@ -245,26 +244,24 @@ trait IndicesRuleLocalIndexTests { ) } } - "some indices are excluded" when { - "todo" in { // todo - assertMatchRuleForIndexRequest( - configured = NonEmptySet.of(indexNameVar("test-index1-*")), - requestIndices = Set(requestedIndex("test-index*"), requestedIndex("-*old")), - modifyRequestContext = _.copy( - allIndicesAndAliases = Set( - fullLocalIndexWithAliases(fullIndexName("test-index1-0001")), - fullLocalIndexWithAliases(fullIndexName("test-index1-0002")), - fullLocalIndexWithAliases(fullIndexName("test-index1-old")), - fullLocalIndexWithAliases(fullIndexName("test-index2-0001")), - fullLocalIndexWithAliases(fullIndexName("test-index2-old")), - ) - ), - filteredRequestedIndices = Set( - requestedIndex("test-index1-0001"), - requestedIndex("test-index1-0002") - ), - ) - } + "some indices are excluded" in { + assertMatchRuleForIndexRequest( + configured = NonEmptySet.of(indexNameVar("test-index1-*")), + requestIndices = Set(requestedIndex("test-index*"), requestedIndex("-*old")), + modifyRequestContext = _.copy( + allIndicesAndAliases = Set( + fullLocalIndexWithAliases(fullIndexName("test-index1-0001")), + fullLocalIndexWithAliases(fullIndexName("test-index1-0002")), + fullLocalIndexWithAliases(fullIndexName("test-index1-old")), + fullLocalIndexWithAliases(fullIndexName("test-index2-0001")), + fullLocalIndexWithAliases(fullIndexName("test-index2-old")), + ) + ), + filteredRequestedIndices = Set( + requestedIndex("test-index1-0001"), + requestedIndex("test-index1-0002") + ), + ) } } "not match" when { diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala index b320345a0a..52e5c1e43f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala @@ -22,8 +22,8 @@ import org.scalatest.EitherValues import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} -import tech.beshu.ror.configuration.ConfigLoading.LoadConfigAction -import tech.beshu.ror.configuration.ConfigLoading.LoadConfigAction.* +import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction +import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction.* import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} @@ -149,10 +149,10 @@ object LoadRawRorConfigTest { } object IdCompiler { - def instance(mocksDef: List[(LoadConfigAction[_], _)]): LoadConfigAction ~> Id = new (LoadConfigAction ~> Id) { - var mocks: List[(LoadConfigAction[_], _)] = mocksDef + def instance(mocksDef: List[(LoadRorConfigAction[_], _)]): LoadRorConfigAction ~> Id = new (LoadRorConfigAction ~> Id) { + var mocks: List[(LoadRorConfigAction[_], _)] = mocksDef - override def apply[A](fa: LoadConfigAction[A]): Id[A] = { + override def apply[A](fa: LoadRorConfigAction[A]): Id[A] = { val (f1, r) = mocks.head mocks = mocks.tail assert(f1 == fa) diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala similarity index 96% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala index a4d750f490..c24061ce6e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedConfigLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala @@ -24,7 +24,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.configuration.{Environment, YamlFileBasedConfigLoader} -class YamlFileBasedConfigLoaderTest extends AnyWordSpec with Inside { +class YamlFileBasedRorConfigLoaderTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = new Environment( envVarsProvider = name => diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala index 3e20fb30aa..eb96fd4333 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala @@ -22,7 +22,7 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import squants.information.{Bytes, Kilobytes} import tech.beshu.ror.utils.TestsUtils.* -import tech.beshu.ror.utils.yaml.RorYamlParser +import tech.beshu.ror.utils.yaml.YamlParser class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { @@ -196,7 +196,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { | auth_key: "admin:container" |""".stripMargin - val result = new RorYamlParser(Bytes(10)).parse(yamlContent) + val result = new YamlParser(Bytes(10)).parse(yamlContent) inside(result) { case Left(parsingFailure) => parsingFailure.message should be("The incoming YAML document exceeds the limit: 10 code points.") @@ -205,5 +205,5 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } private def parseYaml(yamlContent: String): Json = - new RorYamlParser(Kilobytes(100)).parse(yamlContent).toTry.get + new YamlParser(Kilobytes(100)).parse(yamlContent).toTry.get } diff --git a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala index e962486da7..f2ebbb955c 100644 --- a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala +++ b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala @@ -57,7 +57,7 @@ import tech.beshu.ror.utils.js.{JsCompiler, MozillaJsCompiler} import tech.beshu.ror.utils.json.JsonPath import tech.beshu.ror.utils.misc.JwtUtils import tech.beshu.ror.utils.uniquelist.{UniqueList, UniqueNonEmptyList} -import tech.beshu.ror.utils.yaml.RorYamlParser +import tech.beshu.ror.utils.yaml.YamlParser import java.nio.file.Path import java.time.Duration @@ -69,7 +69,7 @@ import scala.util.{Failure, Success} object TestsUtils { implicit val loggingContext: LoggingContext = LoggingContext(Set.empty) - val rorYamlParser = new RorYamlParser(Megabytes(3)) + val rorYamlParser = new YamlParser(Megabytes(3)) val defaultEsVersionForTests: EsVersion = EsVersion(8, 17, 0) From e5d510fe8d82f7b5ce7af1409df28311a5c7c8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 3 Jul 2025 11:36:10 +0200 Subject: [PATCH 007/103] dropped support for not used internal api --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 20 +- .../ror/configuration/RorConfigLoading.scala | 6 - .../loader/RorConfigLoadingInterpreter.scala | 21 +- .../loader/distributed/NodesResponse.scala | 53 ----- .../RawRorConfigLoadingAction.scala | 48 ----- .../loader/distributed/Summary.scala | 110 ---------- .../loader/distributed/domain.scala | 29 --- .../NodeConfigRequestSerializer.scala | 34 --- .../internode/NodeConfigSerializer.scala | 34 --- .../internode/dto/LoadedConfigDTO.scala | 27 --- .../internode/dto/LoadedConfigErrorDto.scala | 194 ------------------ .../internode/dto/NodeConfigDTO.scala | 42 ---- .../internode/dto/NodeConfigRequestDTO.scala | 39 ---- .../distributed/internode/dto/package.scala | 23 --- .../ror/configuration/loader/domain.scala | 3 - .../loader/external/dto/LoadedConfigDTO.scala | 26 --- .../external/dto/NodesResponseWaringDTO.scala | 99 --------- .../loader/external/dto/ResultDTO.scala | 46 ----- .../loader/external/dto/package.scala | 35 ---- .../main/scala/tech/beshu/ror/constants.scala | 1 - .../main/scala/tech/beshu/ror/implicits.scala | 6 + .../ror/es/actions/rrconfig/RRConfig.java | 65 ------ .../actions/rrconfig/RRConfigActionType.scala | 29 --- .../es/actions/rrconfig/RRConfigRequest.java | 49 ----- .../es/actions/rrconfig/RRConfigsRequest.java | 34 --- .../actions/rrconfig/RRConfigsResponse.java | 47 ----- .../rrconfig/TransportRRConfigAction.scala | 115 ----------- .../rrconfig/rest/RestRRConfigAction.scala | 56 ----- .../RestRRConfigActionResponseBuilder.scala | 65 ------ settings.gradle | 60 +++--- .../utils/elasticsearch/RorApiManager.scala | 8 - 31 files changed, 48 insertions(+), 1376 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/NodesResponse.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/domain.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigRequestSerializer.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigSerializer.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigErrorDto.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigRequestDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/package.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/NodesResponseWaringDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/ResultDTO.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/package.scala delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 9b1399bf90..d0ec5b4f28 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,8 +34,9 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.configuration.RorConfigLoading.{ErrorOr, LoadRorConfig} +import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.RorConfigLoading.{ErrorOr, LoadRorConfig} import tech.beshu.ror.configuration.TestRorConfigLoading.* import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.* @@ -66,8 +67,15 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadEsConfig() = { - val action = RorConfigLoading.loadEsConfig(esEnv) - runStartingFailureProgram(action) + EitherT(EsConfig.from(esEnv)) + .leftMap { + case LoadEsConfigError.FileNotFound(file) => + StartingFailure(s"Cannot find elasticsearch settings file: [${file.show}]") + case LoadEsConfigError.MalformedContent(file, message) => + StartingFailure(s"Settings file is malformed: [${file.show}], ${message.show}") + case LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled(typeOfConfiguration) => + StartingFailure(s"Cannot use ROR ${typeOfConfiguration.show} when XPack Security is enabled") + } } private def loadRorConfig(esConfig: EsConfig) = { @@ -113,12 +121,6 @@ class ReadonlyRest(coreFactory: CoreFactory, StartingFailure(message) case LoadedRorConfig.FileNotExist(path) => StartingFailure(s"Cannot find settings file: ${path.show}") - case LoadedRorConfig.EsFileNotExist(path) => - StartingFailure(s"Cannot find elasticsearch settings file: [${path.show}]") - case LoadedRorConfig.EsFileMalformed(path, message) => - StartingFailure(s"Settings file is malformed: [${path.show}], ${message.show}") - case LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled(typeOfConfiguration) => - StartingFailure(s"Cannot use ROR ${typeOfConfiguration.show} when XPack Security is enabled") case LoadedRorConfig.IndexParsingError(message) => StartingFailure(message) case LoadedRorConfig.IndexUnknownStructure => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala index a18d6009b0..01aa137e8f 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala @@ -19,7 +19,6 @@ package tech.beshu.ror.configuration import cats.free.Free import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.es.EsEnv object RorConfigLoading { type ErrorOr[A] = LoadedRorConfig.Error Either A @@ -28,8 +27,6 @@ object RorConfigLoading { sealed trait LoadRorConfigAction[A] object LoadRorConfigAction { - final case class LoadEsConfig(env: EsEnv) - extends LoadRorConfigAction[ErrorOr[EsConfig]] final case class ForceLoadRorConfigFromFile(settings: LoadFromFileSettings) extends LoadRorConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] final case class LoadRorConfigFromFile(settings: LoadFromFileSettings) @@ -44,9 +41,6 @@ object RorConfigLoading { def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = Free.liftF(LoadRorConfigAction.LoadRorConfigFromFile(settings)) - def loadEsConfig(env: EsEnv): LoadRorConfig[ErrorOr[EsConfig]] = - Free.liftF(LoadRorConfigAction.LoadEsConfig(env)) - def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = Free.liftF(LoadRorConfigAction.ForceLoadRorConfigFromFile(settings)) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala index 3b9c18dc23..2642ec489e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala @@ -22,15 +22,13 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError.* import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction import tech.beshu.ror.configuration.RorProperties.LoadingDelay import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} import tech.beshu.ror.configuration.loader.LoadedRorConfig.* import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{EsConfig, RawRorConfigYamlParser, RorConfigLoading} +import tech.beshu.ror.configuration.{RawRorConfigYamlParser, RorConfigLoading} import tech.beshu.ror.implicits.* object RorConfigLoadingInterpreter extends Logging { @@ -38,23 +36,6 @@ object RorConfigLoadingInterpreter extends Logging { def create(indexConfigManager: IndexConfigManager) (implicit systemContext: SystemContext): LoadRorConfigAction ~> Task = new (LoadRorConfigAction ~> Task) { override def apply[A](fa: LoadRorConfigAction[A]): Task[A] = fa match { - case RorConfigLoading.LoadRorConfigAction.LoadEsConfig(env) => - logger.info(s"Loading Elasticsearch settings from file: ${env.elasticsearchConfig.show}") - EsConfig - .from(env) - .map(_.left.map { - case LoadEsConfigError.FileNotFound(file) => - EsFileNotExist(file.path) - case LoadEsConfigError.MalformedContent(file, msg) => - EsFileMalformed(file.path, msg) - case LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled(aType) => - CannotUseRorConfigurationWhenXpackSecurityIsEnabled( - aType match { - case SettingsType.Ssl => "SSL configuration" - case SettingsType.Fips => "FIBS configuration" - } - ) - }) case RorConfigLoading.LoadRorConfigAction.ForceLoadRorConfigFromFile(settings) => val rorSettingsFile = settings.rorSettingsFile val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/NodesResponse.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/NodesResponse.scala deleted file mode 100644 index d18f64c08a..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/NodesResponse.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed - -import cats.Eq -import cats.implicits.* -import io.circe.syntax.* -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.configuration.loader.external.dto.ResultDTO - -final case class NodesResponse private(resultDTO: ResultDTO) extends AnyVal - -object NodesResponse { - def create(localNode: NodeId, - responses: List[NodeResponse], - failures: List[NodeError]): NodesResponse = { - NodesResponse(ResultDTO.create(Summary.create(localNode, responses, failures))) - } - - implicit class Ops(nodesResponse: NodesResponse) { - def toJson: String = nodesResponse.resultDTO.asJson.noSpaces - } - - final case class NodeId(value: String) extends AnyVal - object NodeId { - implicit val eqNodeId: Eq[NodeId] = Eq.by(_.value) - } - final case class NodeResponse(nodeId: NodeId, loadedConfig: Either[LoadedRorConfig.Error, LoadedRorConfig[String]]) - final case class NodeError(nodeId: NodeId, cause: NodeError.Cause) - object NodeError { - sealed trait Cause - case object RorConfigActionNotFound extends Cause - case object Timeout extends Cause - final case class Unknown(detailedMessage: String) extends Cause - } -} - - - diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala deleted file mode 100644 index 8f9c95e371..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/RawRorConfigLoadingAction.scala +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed - -import cats.data.EitherT -import monix.eval.Task -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfig -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.index.IndexConfigManager -import tech.beshu.ror.configuration.loader.{RorConfigLoadingInterpreter, LoadRawRorConfig, LoadedRorConfig} -import tech.beshu.ror.configuration.{RorConfigLoading, RawRorConfig} -import tech.beshu.ror.es.EsEnv - -object RawRorConfigLoadingAction { - - // todo: IndexConfigManager or maybe not? - def loadFromIndex(env: EsEnv, indexConfigManager: IndexConfigManager) - (implicit systemContext: SystemContext): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { - val compiler = RorConfigLoadingInterpreter.create(indexConfigManager) - (for { - esConfig <- EitherT(RorConfigLoading.loadEsConfig(env)) - loadedConfig <- esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - EitherT.leftT[LoadRorConfig, LoadedRorConfig[RawRorConfig]]( - LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled("todo"): LoadedRorConfig.Error // todo: fixme - ) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - EitherT(LoadRawRorConfig.loadFromIndex(settings)) - } - } yield loadedConfig).value.foldMap(compiler) - } - -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala deleted file mode 100644 index 3e9e42f45d..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/Summary.scala +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed - -import cats.implicits.* -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} - -import scala.language.postfixOps - -object Summary { - case object CurrentNodeHaveToProduceResult extends Exception - - sealed trait Error - final case class CurrentNodeConfigError(error: LoadedRorConfig.Error) extends Error - final case class CurrentNodeResponseError(detailedMessage: String) extends Error - case object CurrentNodeResponseTimeoutError extends Error - - sealed trait Warning - final case class NodeResponseTimeoutWarning(nodeId: NodeId) extends Warning - final case class NodeReturnedConfigError(nodeId: NodeId, error: LoadedRorConfig.Error) extends Warning - final case class NodeReturnedUnknownError(nodeId: NodeId, detailedMessage: String) extends Warning - final case class NodeForcedFileConfig(nodeId: NodeId) extends Warning - final case class NodeReturnedDifferentConfig(nodeId: NodeId, loadedConfig: LoadedRorConfig[String]) extends Warning - final case class Result(config: LoadedRorConfig[String], warnings: List[Warning]) - - - def create(currentNodeId: NodeId, nodesResponses: List[NodeResponse], failures: List[NodeError]): Either[Error, Result] = { - findCurrentNodeResponse(currentNodeId, nodesResponses) match { - case Some(NodeResponse(_, Right(loadedConfig))) => - val warnings = createWarnings(nodesResponses, loadedConfig, failures) - Result(loadedConfig, warnings) asRight - case Some(NodeResponse(_, Left(error))) => CurrentNodeConfigError(error) asLeft - case None => findCurrentNodeFailure(currentNodeId, failures) match { - case Some(NodeError(_, cause)) => cause match { - case NodeError.RorConfigActionNotFound => throw CurrentNodeHaveToProduceResult - case NodeError.Timeout => CurrentNodeResponseTimeoutError asLeft - case NodeError.Unknown(detailedMessage) => CurrentNodeResponseError(detailedMessage) asLeft - } - case None => throw CurrentNodeHaveToProduceResult - } - } - } - - private def createWarnings(nodesResponses: List[NodeResponse], - loadedConfig: LoadedRorConfig[String], - failures: List[NodeError]): List[Warning] = { - createNodeErrorWarnings(nodesResponses) ++ - createNodeNodeForcedFileConfigWarnings(nodesResponses) ++ - createNodeReturnedDifferentConfigWarnings(loadedConfig, nodesResponses) ++ - createNodeReturnedUnknownError(failures) ++ - createNodeResponseTimeoutWarnings(failures) ++ - Nil - } - - private def findCurrentNodeFailure(currentNodeId: NodeId, nodesResponses: List[NodeError]) = - nodesResponses.find(_.nodeId === currentNodeId) - - private def findCurrentNodeResponse(currentNodeId: NodeId, nodesResponses: List[NodeResponse]) = - nodesResponses.find(_.nodeId === currentNodeId) - - private def createNodeReturnedUnknownError(failures: List[NodeError]): List[NodeReturnedUnknownError] = - failures.flatMap { - case NodeError(nodeId, NodeError.Unknown(detailedMessage)) => NodeReturnedUnknownError(nodeId, detailedMessage) :: Nil - case _ => Nil - } - - private def createNodeErrorWarnings(otherResponses: List[NodeResponse]): List[NodeReturnedConfigError] = - otherResponses.flatMap { - case NodeResponse(nodeId, Left(error)) => NodeReturnedConfigError(nodeId, error) :: Nil - case _ => Nil - } - - private def createNodeResponseTimeoutWarnings(failures: List[NodeError]): List[NodeResponseTimeoutWarning] = - failures.flatMap { - case NodeError(nodeId, NodeError.Timeout) => NodeResponseTimeoutWarning(nodeId) :: Nil - case _ => Nil - } - - private def createNodeNodeForcedFileConfigWarnings(otherResponses: List[NodeResponse]): List[NodeForcedFileConfig] = - otherResponses.flatMap { - case NodeResponse(nodeId, Right(LoadedRorConfig(_))) => NodeForcedFileConfig(nodeId) :: Nil - case _ => Nil - } - - private def createNodeReturnedDifferentConfigWarnings(currentNodeConfig: LoadedRorConfig[String], - otherResponses: List[NodeResponse]): List[NodeReturnedDifferentConfig] = { - otherResponses.foldLeft(List.empty[NodeReturnedDifferentConfig]) { - case (warnings, NodeResponse(_, Right(`currentNodeConfig`))) => warnings - case (warnings, NodeResponse(nodeId, Right(loadedConfig))) => NodeReturnedDifferentConfig(nodeId, loadedConfig) :: warnings - case (warnings, _) => warnings - } - } - -} - diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/domain.scala deleted file mode 100644 index 6165c29012..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/domain.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed - -import tech.beshu.ror.configuration.loader.LoadedRorConfig - -import scala.concurrent.duration.* -import scala.language.postfixOps - -final case class NodeConfig(loadedConfig: Either[LoadedRorConfig.Error, LoadedRorConfig[String]]) -final case class Timeout(nanos: Long) extends AnyVal -final case class NodeConfigRequest(timeout: Timeout) -object NodeConfigRequest { - val defaultTimeout: Timeout = Timeout(nanos = (10 seconds).toNanos) -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigRequestSerializer.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigRequestSerializer.scala deleted file mode 100644 index 5531e56209..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigRequestSerializer.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode - -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest -import tech.beshu.ror.configuration.loader.distributed.internode.dto.NodeConfigRequestDTO - -object NodeConfigRequestSerializer { - - import io.circe.parser - import io.circe.syntax.* - - def serialize(nodeConfigRequest: NodeConfigRequest): String = { - NodeConfigRequestDTO.create(nodeConfigRequest).asJson.noSpaces - } - - def parse(str: String): NodeConfigRequest = { - parser.decode[NodeConfigRequestDTO](str).map(NodeConfigRequestDTO.fromDto).toTry.get - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigSerializer.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigSerializer.scala deleted file mode 100644 index dfc6714c20..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/NodeConfigSerializer.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode - -import tech.beshu.ror.configuration.loader.distributed.NodeConfig -import tech.beshu.ror.configuration.loader.distributed.internode.dto.NodeConfigDTO - -object NodeConfigSerializer { - - import io.circe.parser - import io.circe.syntax.* - - def serialize(nodeConfig: NodeConfig): String = { - NodeConfigDTO.create(nodeConfig).asJson.noSpaces - } - - def parse(str: String): NodeConfig = { - parser.decode[NodeConfigDTO](str).map(NodeConfigDTO.fromDto).toTry.get - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala deleted file mode 100644 index 37ef328275..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigDTO.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode.dto - -import tech.beshu.ror.configuration.loader.LoadedRorConfig - -final case class LoadedConfigDTO(value: String) -object LoadedConfigDTO { - - def create(o: LoadedRorConfig[String]): LoadedConfigDTO = LoadedConfigDTO(o.value) - - def fromDto(o: LoadedConfigDTO): LoadedRorConfig[String] = LoadedRorConfig(o.value) -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigErrorDto.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigErrorDto.scala deleted file mode 100644 index 90aa27dd29..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/LoadedConfigErrorDto.scala +++ /dev/null @@ -1,194 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode.dto - -import io.circe.{Codec, Decoder, Encoder} -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.utils.CirceOps.* - -import java.nio.file.Paths - -sealed trait LoadedConfigErrorDto - -object LoadedConfigErrorDto { - - implicit val codec: Codec[LoadedConfigErrorDto] = codecWithTypeDiscriminator( - encode = { - case dto: FileParsingErrorDTO => - derivedEncoderWithType[FileParsingErrorDTO]("FileParsingErrorDTO")(dto) - case dto: FileNotExistDTO => - derivedEncoderWithType[FileNotExistDTO]("FileNotExistDTO")(dto) - case dto: EsFileNotExistDTO => - derivedEncoderWithType[EsFileNotExistDTO]("EsFileNotExistDTO")(dto) - case dto: EsFileMalformedDTO => - derivedEncoderWithType[EsFileMalformedDTO]("EsFileMalformedDTO")(dto) - case dto: CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO => - derivedEncoderWithType[CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO]("CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO")(dto) - case dto: IndexParsingErrorDTO => - derivedEncoderWithType[IndexParsingErrorDTO]("FileParsingErrorDTO")(dto) - case IndexUnknownStructureDTO => - derivedEncoderWithType[IndexUnknownStructureDTO.type]("IndexUnknownStructureDTO")(IndexUnknownStructureDTO) - case IndexNotExistDTO => - derivedEncoderWithType[IndexNotExistDTO.type]("IndexNotExistDTO")(IndexNotExistDTO) - }, - decoders = Map( - "FileParsingErrorDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, FileParsingErrorDTO], - "FileNotExistDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, FileNotExistDTO], - "EsFileNotExistDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, EsFileNotExistDTO], - "EsFileMalformedDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, EsFileMalformedDTO], - "CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO], - "FileParsingErrorDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, FileParsingErrorDTO], - "IndexUnknownStructureDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, IndexUnknownStructureDTO.type], - "IndexNotExistDTO" -> derivedDecoderOfSubtype[LoadedConfigErrorDto, IndexNotExistDTO.type], - ) - ) - - def create(error: LoadedRorConfig.Error): LoadedConfigErrorDto = error match { - case o: LoadedRorConfig.FileParsingError => FileParsingErrorDTO.create(o) - case o: LoadedRorConfig.FileNotExist => FileNotExistDTO.create(o) - case o: LoadedRorConfig.EsFileNotExist => EsFileNotExistDTO.create(o) - case o: LoadedRorConfig.EsFileMalformed => EsFileMalformedDTO.create(o) - case o: LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled => - CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO.create(o) - case o: LoadedRorConfig.IndexParsingError => IndexParsingErrorDTO.create(o) - case _: LoadedRorConfig.IndexUnknownStructure.type => IndexUnknownStructureDTO - case _: LoadedRorConfig.IndexNotExist.type => IndexNotExistDTO - } - - def fromDto(o: LoadedConfigErrorDto): LoadedRorConfig.Error = o match { - case o: FileParsingErrorDTO => FileParsingErrorDTO.fromDto(o) - case o: FileNotExistDTO => FileNotExistDTO.fromDto(o) - case o: EsFileNotExistDTO => EsFileNotExistDTO.fromDto(o) - case o: EsFileMalformedDTO => EsFileMalformedDTO.fromDto(o) - case o: CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO => - CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO.fromDto(o) - case o: IndexParsingErrorDTO => IndexParsingErrorDTO.fromDto(o) - case _: IndexUnknownStructureDTO.type => LoadedRorConfig.IndexUnknownStructure - case _: IndexNotExistDTO.type => LoadedRorConfig.IndexNotExist - } - - final case class FileParsingErrorDTO(message: String) extends LoadedConfigErrorDto - object FileParsingErrorDTO { - def create(o: LoadedRorConfig.FileParsingError): FileParsingErrorDTO = - new FileParsingErrorDTO( - message = o.message, - ) - - def fromDto(o: FileParsingErrorDTO): LoadedRorConfig.FileParsingError = LoadedRorConfig.FileParsingError( - message = o.message, - ) - implicit class Ops(o: FileParsingErrorDTO) { - implicit def fromDto: LoadedRorConfig.FileParsingError = FileParsingErrorDTO.fromDto(o) - } - } - - final case class FileNotExistDTO(path: String) extends LoadedConfigErrorDto - object FileNotExistDTO { - def create(o: LoadedRorConfig.FileNotExist): FileNotExistDTO = - new FileNotExistDTO( - path = o.path.toString, - ) - - def fromDto(o: FileNotExistDTO): LoadedRorConfig.FileNotExist = LoadedRorConfig.FileNotExist( - path = Paths.get(o.path), - ) - implicit class Ops(o: FileNotExistDTO) { - implicit def fromDto: LoadedRorConfig.FileNotExist = FileNotExistDTO.fromDto(o) - } - } - - final case class EsFileNotExistDTO(path: String) extends LoadedConfigErrorDto - object EsFileNotExistDTO { - def create(o: LoadedRorConfig.EsFileNotExist): EsFileNotExistDTO = - new EsFileNotExistDTO( - path = o.path.toString, - ) - - def fromDto(o: EsFileNotExistDTO): LoadedRorConfig.EsFileNotExist = LoadedRorConfig.EsFileNotExist( - path = Paths.get(o.path), - ) - implicit class Ops(o: EsFileNotExistDTO) { - implicit def fromDto: LoadedRorConfig.EsFileNotExist = EsFileNotExistDTO.fromDto(o) - } - } - - final case class EsFileMalformedDTO(path: String, message: String) extends LoadedConfigErrorDto - object EsFileMalformedDTO { - def create(o: LoadedRorConfig.EsFileMalformed): EsFileMalformedDTO = - new EsFileMalformedDTO( - path = o.path.toString, - message = o.message, - ) - - def fromDto(o: EsFileMalformedDTO): LoadedRorConfig.EsFileMalformed = LoadedRorConfig.EsFileMalformed( - path = Paths.get(o.path), - message = o.message, - ) - implicit class Ops(o: EsFileMalformedDTO) { - implicit def fromDto: LoadedRorConfig.EsFileMalformed = EsFileMalformedDTO.fromDto(o) - } - } - - final case class CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO(typeOfConfiguration: String) extends LoadedConfigErrorDto - object CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO { - def create(o: LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled): CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO = - new CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO( - typeOfConfiguration = o.typeOfConfiguration - ) - - def fromDto(o: CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO): LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled = - LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled( - typeOfConfiguration = o.typeOfConfiguration - ) - implicit class Ops(o: CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO) { - implicit def fromDto: LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled = - CannotUseRorConfigurationWhenXpackSecurityIsEnabledDTO.fromDto(o) - } - } - - final case class IndexParsingErrorDTO(message: String) extends LoadedConfigErrorDto - object IndexParsingErrorDTO { - def create(o: LoadedRorConfig.IndexParsingError): IndexParsingErrorDTO = - new IndexParsingErrorDTO( - message = o.message, - ) - - def fromDto(o: IndexParsingErrorDTO): LoadedRorConfig.IndexParsingError = LoadedRorConfig.IndexParsingError( - message = o.message, - ) - implicit class Ops(o: IndexParsingErrorDTO) { - implicit def fromDto: LoadedRorConfig.IndexParsingError = IndexParsingErrorDTO.fromDto(o) - } - } - - case object IndexUnknownStructureDTO extends LoadedConfigErrorDto { - implicit lazy val codecIndexUnknownStructureDto: Codec[IndexUnknownStructureDTO.type] = { - val enc = Encoder.encodeString.contramap[IndexUnknownStructureDTO.type](_ => "unknown_structure") - val dec = Decoder.decodeString.map(_ => IndexUnknownStructureDTO) - Codec.from(dec, enc) - } - } - - case object IndexNotExistDTO extends LoadedConfigErrorDto { - implicit lazy val codecIndexNotFoundDto: Codec[IndexNotExistDTO.type] = { - val enc = Encoder.encodeString.contramap[IndexNotExistDTO.type](_ => "index_not_exist") - val dec = Decoder.decodeString.map(_ => IndexNotExistDTO) - Codec.from(dec, enc) - } - } - -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigDTO.scala deleted file mode 100644 index 09c220cb95..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigDTO.scala +++ /dev/null @@ -1,42 +0,0 @@ -package tech.beshu.ror.configuration.loader.distributed.internode.dto - -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ - -import cats.implicits.* -import io.circe.Codec -import io.circe.generic.semiauto.deriveCodec -import tech.beshu.ror.configuration.loader.distributed.NodeConfig - -final case class NodeConfigDTO(loadedConfig: Either[LoadedConfigErrorDto, LoadedConfigDTO]) - -object NodeConfigDTO { - - implicit val codec: Codec[NodeConfigDTO] = deriveCodec - - def create(o: NodeConfig): NodeConfigDTO = - new NodeConfigDTO( - loadedConfig = o.loadedConfig.bimap(LoadedConfigErrorDto.create, LoadedConfigDTO.create), - ) - - def fromDto(o: NodeConfigDTO): NodeConfig = NodeConfig( - loadedConfig = o.loadedConfig.bimap(LoadedConfigErrorDto.fromDto, LoadedConfigDTO.fromDto), - ) - implicit class Ops(o: NodeConfigDTO) { - implicit def fromDto: NodeConfig = NodeConfigDTO.fromDto(o) - } -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigRequestDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigRequestDTO.scala deleted file mode 100644 index db56d8912d..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/NodeConfigRequestDTO.scala +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode.dto - -import io.circe.Codec -import io.circe.generic.semiauto.deriveCodec -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} - -final case class NodeConfigRequestDTO(nanos: Long) - -object NodeConfigRequestDTO { - implicit val codec: Codec[NodeConfigRequestDTO] = deriveCodec - - def create(o: NodeConfigRequest): NodeConfigRequestDTO = - new NodeConfigRequestDTO( - nanos = o.timeout.nanos, - ) - - def fromDto(o: NodeConfigRequestDTO): NodeConfigRequest = NodeConfigRequest( - timeout = Timeout(o.nanos), - ) - implicit class Ops(o: NodeConfigRequestDTO) { - implicit def fromDto: NodeConfigRequest = NodeConfigRequestDTO.fromDto(o) - } -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/package.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/package.scala deleted file mode 100644 index 4b85c22c62..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/distributed/internode/dto/package.scala +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.distributed.internode - -import io.circe.{Codec, Decoder, Encoder} - -package object dto { - implicit def codecEither[A: Decoder : Encoder, B: Decoder : Encoder]: Codec[Either[A, B]] = io.circe.generic.semiauto.deriveCodec -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala index 787611385e..1c7bf5923d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala @@ -24,9 +24,6 @@ object LoadedRorConfig { sealed trait Error final case class FileParsingError(message: String) extends LoadedRorConfig.Error final case class FileNotExist(path: Path) extends LoadedRorConfig.Error - final case class EsFileNotExist(path: Path) extends LoadedRorConfig.Error - final case class EsFileMalformed(path: Path, message: String) extends LoadedRorConfig.Error - final case class CannotUseRorConfigurationWhenXpackSecurityIsEnabled(typeOfConfiguration: String) extends LoadedRorConfig.Error sealed trait LoadingIndexError final case class IndexParsingError(message: String) extends LoadedRorConfig.Error with LoadingIndexError diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala deleted file mode 100644 index 63e3a97f15..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/LoadedConfigDTO.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.external.dto - -import tech.beshu.ror.configuration.loader.LoadedRorConfig - -final case class LoadedConfigDTO(raw: String) - -object LoadedConfigDTO { - def create(o: LoadedRorConfig[String]): LoadedConfigDTO = LoadedConfigDTO(o.value) -} - diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/NodesResponseWaringDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/NodesResponseWaringDTO.scala deleted file mode 100644 index 59970b82a1..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/NodesResponseWaringDTO.scala +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.external.dto - -import cats.implicits.* -import io.circe.Codec -import tech.beshu.ror.configuration.loader.distributed.Summary -import tech.beshu.ror.configuration.loader.distributed.Summary.{NodeForcedFileConfig, NodeReturnedDifferentConfig} -import tech.beshu.ror.utils.CirceOps.* - -sealed trait NodesResponseWaringDTO - -object NodesResponseWaringDTO { - - implicit val codec: Codec[NodesResponseWaringDTO] = codecWithTypeDiscriminator( - encode = { - case dto: NODE_RETURNED_DIFFERENT_CONFIG => - derivedEncoderWithType[NODE_RETURNED_DIFFERENT_CONFIG]("NODE_RETURNED_DIFFERENT_CONFIG")(dto) - case dto: NODE_FORCED_FILE_CONFIG => - derivedEncoderWithType[NODE_FORCED_FILE_CONFIG]("NODE_FORCED_FILE_CONFIG")(dto) - case dto: NODE_RETURNED_CONFIG_ERROR => - derivedEncoderWithType[NODE_RETURNED_CONFIG_ERROR]("NODE_RETURNED_CONFIG_ERROR")(dto) - case dto: NODE_RETURNED_UNKNOWN_ERROR => - derivedEncoderWithType[NODE_RETURNED_UNKNOWN_ERROR]("NODE_RETURNED_UNKNOWN_ERROR")(dto) - case dto: NODE_RESPONSE_TIMEOUT_ERROR => - derivedEncoderWithType[NODE_RESPONSE_TIMEOUT_ERROR]("NODE_RESPONSE_TIMEOUT_ERROR")(dto) - }, - decoders = Map( - "NODE_RETURNED_DIFFERENT_CONFIG" -> derivedDecoderOfSubtype[NodesResponseWaringDTO, NODE_RETURNED_DIFFERENT_CONFIG], - "NODE_FORCED_FILE_CONFIG" -> derivedDecoderOfSubtype[NodesResponseWaringDTO, NODE_FORCED_FILE_CONFIG], - "NODE_RETURNED_CONFIG_ERROR" -> derivedDecoderOfSubtype[NodesResponseWaringDTO, NODE_RETURNED_CONFIG_ERROR], - "NODE_RETURNED_UNKNOWN_ERROR" -> derivedDecoderOfSubtype[NodesResponseWaringDTO, NODE_RETURNED_UNKNOWN_ERROR], - "NODE_RESPONSE_TIMEOUT_ERROR" -> derivedDecoderOfSubtype[NodesResponseWaringDTO, NODE_RESPONSE_TIMEOUT_ERROR], - ) - ) - - def create(warning: Summary.Warning): NodesResponseWaringDTO = warning match { - case w: Summary.NodeReturnedConfigError => NODE_RETURNED_CONFIG_ERROR.create(w) - case w: Summary.NodeReturnedUnknownError => NODE_RETURNED_UNKNOWN_ERROR.create(w) - case w: Summary.NodeForcedFileConfig => NODE_FORCED_FILE_CONFIG.create(w) - case w: Summary.NodeReturnedDifferentConfig => NODE_RETURNED_DIFFERENT_CONFIG.create(w) - case w: Summary.NodeResponseTimeoutWarning => NODE_RESPONSE_TIMEOUT_ERROR.create(w) - } - final case class NODE_RETURNED_DIFFERENT_CONFIG(nodeId: String, loadedConfig: LoadedConfigDTO) extends NodesResponseWaringDTO - object NODE_RETURNED_DIFFERENT_CONFIG { - def create(o: NodeReturnedDifferentConfig): NODE_RETURNED_DIFFERENT_CONFIG = - new NODE_RETURNED_DIFFERENT_CONFIG( - nodeId = o.nodeId.value, - loadedConfig = LoadedConfigDTO.create(o.loadedConfig), - ) - } - final case class NODE_FORCED_FILE_CONFIG(nodeId: String) extends NodesResponseWaringDTO - object NODE_FORCED_FILE_CONFIG { - def create(o: NodeForcedFileConfig): NODE_FORCED_FILE_CONFIG = - new NODE_FORCED_FILE_CONFIG( - nodeId = o.nodeId.value, - ) - } - final case class NODE_RETURNED_CONFIG_ERROR(nodeId: String, error: String) extends NodesResponseWaringDTO - object NODE_RETURNED_CONFIG_ERROR { - def create(o: Summary.NodeReturnedConfigError): NODE_RETURNED_CONFIG_ERROR = - new NODE_RETURNED_CONFIG_ERROR( - nodeId = o.nodeId.value, - error = o.error.show, - ) - } - final case class NODE_RETURNED_UNKNOWN_ERROR(nodeId: String, detailedMessage: String) extends NodesResponseWaringDTO - object NODE_RETURNED_UNKNOWN_ERROR { - def create(o: Summary.NodeReturnedUnknownError): NODE_RETURNED_UNKNOWN_ERROR = - new NODE_RETURNED_UNKNOWN_ERROR( - nodeId = o.nodeId.value, - detailedMessage = o.detailedMessage, - ) - } - final case class NODE_RESPONSE_TIMEOUT_ERROR(nodeId: String) extends NodesResponseWaringDTO - object NODE_RESPONSE_TIMEOUT_ERROR { - def create(o: Summary.NodeResponseTimeoutWarning): NODE_RESPONSE_TIMEOUT_ERROR = - new NODE_RESPONSE_TIMEOUT_ERROR( - nodeId = o.nodeId.value, - ) - } -} - - - diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/ResultDTO.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/ResultDTO.scala deleted file mode 100644 index ec70b27224..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/ResultDTO.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.external.dto - -import cats.implicits.* -import io.circe.Codec -import io.circe.generic.semiauto.deriveCodec -import tech.beshu.ror.configuration.loader.distributed.Summary -import tech.beshu.ror.configuration.loader.distributed.Summary.{Error, Result} - -final case class ResultDTO(config: Option[LoadedConfigDTO], - warnings: List[NodesResponseWaringDTO], - error: Option[String]) - -object ResultDTO { - def create(o: Either[Error, Result]): ResultDTO = - o.bimap(createError, createResult).merge - - private def createResult(result: Result) = - ResultDTO(LoadedConfigDTO.create(result.config).some, result.warnings.map(NodesResponseWaringDTO.create), None) - - private def createError(error: Error) = { - val message = error match { - case Summary.CurrentNodeResponseError(detailedMessage) => s"current node response error: ${detailedMessage.show}" - case Summary.CurrentNodeConfigError(error) => show"current node returned error: ${error.show}" - case Summary.CurrentNodeResponseTimeoutError => "current node response timeout" - } - ResultDTO(None, Nil, message.some) - } - - implicit val codec: Codec[ResultDTO] = deriveCodec -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/package.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/package.scala deleted file mode 100644 index acf68a3df0..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/external/dto/package.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader.external - -import cats.Show -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.implicits.* - -package object dto { - implicit val showLoadedConfigError: Show[LoadedRorConfig.Error] = Show.show { - case LoadedRorConfig.FileNotExist(path) => s"""file not exist: ${path.show}""" - case LoadedRorConfig.FileParsingError(message) => s"""file parsing error: ${message.show}""" - case LoadedRorConfig.EsFileNotExist(path) => s"""ES file not exist: ${path.show}""" - case LoadedRorConfig.EsFileMalformed(path, message) => s"""ES file malformed: ${path.show} ${message.show}""" - case LoadedRorConfig.CannotUseRorConfigurationWhenXpackSecurityIsEnabled(typeOfConfiguration) => - s"""ROR ${typeOfConfiguration.show} cannot be used when XPack Security is enabled""" - case LoadedRorConfig.IndexParsingError(message) => s"""index parsing error: ${message.show}""" - case LoadedRorConfig.IndexUnknownStructure => "index unknown structure" - case LoadedRorConfig.IndexNotExist => "index not exist" - } -} diff --git a/core/src/main/scala/tech/beshu/ror/constants.scala b/core/src/main/scala/tech/beshu/ror/constants.scala index 4f5f2c29e4..3b486c9d76 100644 --- a/core/src/main/scala/tech/beshu/ror/constants.scala +++ b/core/src/main/scala/tech/beshu/ror/constants.scala @@ -43,7 +43,6 @@ object constants { val PROVIDE_AUTH_MOCK_PATH = "/_readonlyrest/admin/config/test/authmock/" val PROVIDE_INDEX_CONFIG_PATH = "/_readonlyrest/admin/config/" val PROVIDE_FILE_CONFIG_PATH = "/_readonlyrest/admin/config/file/" - val MANAGE_ROR_CONFIG_PATH = "/_readonlyrest/admin/config/load" val FIELDS_TRANSIENT = "_fields" diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 1d3ebf6df4..7440447df6 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -59,6 +59,7 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError.{KibanaRuleTogetherWith, KibanaUserDataRuleTogetherWith} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext +import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* @@ -334,6 +335,11 @@ trait LogsShowInstances s"JWT variables are not allowed to be used in Groups rule" } + implicit val settingsTypeShow: Show[SettingsType] = Show.show { + case SettingsType.Ssl => "SSL configuration" + case SettingsType.Fips => "FIBS configuration" + } + def obfuscatedHeaderShow(obfuscatedHeaders: Iterable[Header.Name]): Show[Header] = { Show.show[Header] { case Header(name, _) if obfuscatedHeaders.exists(_ === name) => s"${name.show}=" diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 21317a9d83..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.injection.guice.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 75d052eb16..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0db5eda205..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index f0ffb95859..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig, Void]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 59203f11f5..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.rest.* -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import java.util -import java.util.function.Supplier -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 5f1ba63898..0000000000 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/settings.gradle b/settings.gradle index 6ecd2787b8..e2539707c7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,36 +26,36 @@ rootProject.name = 'readonlyrest' include 'ror-shadowed-libs' include 'audit' include 'core' -include 'es67x' -include 'es70x' -include 'es72x' -include 'es73x' -include 'es74x' -include 'es77x' -include 'es78x' -include 'es79x' -include 'es710x' -include 'es711x' -include 'es714x' -include 'es716x' -include 'es717x' -include 'es80x' -include 'es81x' -include 'es82x' -include 'es83x' -include 'es84x' -include 'es85x' -include 'es87x' -include 'es88x' -include 'es89x' -include 'es810x' -include 'es811x' -include 'es812x' -include 'es813x' -include 'es814x' -include 'es815x' -include 'es816x' -include 'es818x' +//include 'es67x' +//include 'es70x' +//include 'es72x' +//include 'es73x' +//include 'es74x' +//include 'es77x' +//include 'es78x' +//include 'es79x' +//include 'es710x' +//include 'es711x' +//include 'es714x' +//include 'es716x' +//include 'es717x' +//include 'es80x' +//include 'es81x' +//include 'es82x' +//include 'es83x' +//include 'es84x' +//include 'es85x' +//include 'es87x' +//include 'es88x' +//include 'es89x' +//include 'es810x' +//include 'es811x' +//include 'es812x' +//include 'es813x' +//include 'es814x' +//include 'es815x' +//include 'es816x' +//include 'es818x' include 'es90x' include 'ror-tools-core' include 'ror-tools' diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala index face0f23fe..e70f72c915 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala @@ -51,10 +51,6 @@ class RorApiManager(client: RestClient, call(createGetRorInIndexConfigRequest(), new RorApiJsonResponse(_)) } - def loadRorCurrentConfig(additionalParams: Map[String, String] = Map.empty): RorApiJsonResponse = { - call(createLoadRorCurrentConfigRequest(additionalParams), new RorApiJsonResponse(_)) - } - def updateRorInIndexConfig(config: String): RorApiResponseWithBusinessStatus = { call(createUpdateRorInIndexConfigRequest(config), new RorApiResponseWithBusinessStatus(_)) } @@ -206,10 +202,6 @@ class RorApiManager(client: RestClient, new HttpGet(client.from("/_readonlyrest/admin/config/test/authmock")) } - private def createLoadRorCurrentConfigRequest(additionalParams: Map[String, String]) = { - new HttpGet(client.from("/_readonlyrest/admin/config/load", additionalParams)) - } - final class RorApiJsonResponse(override val response: HttpResponse) extends JsonResponse(response) From 7f6649a04addb65c1d7c5f4fe4c9a35ce2d0c8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 3 Jul 2025 15:47:34 +0200 Subject: [PATCH 008/103] refactoring --- core/build.gradle | 1 - .../tech/beshu/ror/boot/ReadonlyRest.scala | 61 ++++------ .../ror/configuration/RorConfigLoading.scala | 100 ++++++++++++---- .../configuration/TestRorConfigLoading.scala | 59 +++++++-- .../loader/LoadRawRorConfig.scala | 50 ++++---- .../loader/LoadRawTestRorConfig.scala | 35 +++--- .../loader/RorConfigLoadingInterpreter.scala | 113 ------------------ .../TestRorConfigLoadingInterpreter.scala | 85 ------------- .../ror/configuration/loader/domain.scala | 1 + 9 files changed, 200 insertions(+), 305 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala diff --git a/core/build.gradle b/core/build.gradle index 8e6cef2ab4..ccb15a7b0f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -78,7 +78,6 @@ dependencies { api group: 'io.circe', name: 'circe-parser_3', version: '0.14.6' api group: 'io.circe', name: 'circe-refined_3', version: '0.14.6' api group: 'commons-codec', name: 'commons-codec', version: '1.15' - api group: 'org.typelevel', name: 'cats-free_3', version: '2.12.0' api group: 'com.beachape', name: 'enumeratum_3', version: '1.7.5' api group: 'com.hrakaroo', name: 'glob', version: '0.9.0' api group: 'com.comcast', name: 'ip4s-core_3', version: '2.0.4' diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index d0ec5b4f28..48940ea945 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -36,8 +36,6 @@ import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.RorConfigLoading.{ErrorOr, LoadRorConfig} -import tech.beshu.ror.configuration.TestRorConfigLoading.* import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} @@ -78,41 +76,49 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadRorConfig(esConfig: EsConfig) = { - val action = esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + private def loadRorConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedRorConfig[RawRorConfig]] = { + esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - LoadRawRorConfig.loadFromFile(settings) + EitherT(LoadRawRorConfig.loadFromFile(settings)) + .leftMap(toStartingFailure) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => // todo: move // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - LoadRawRorConfig.loadFromIndexWithFileFallback(settings, fallbackSettings) + EitherT(LoadRawRorConfig.loadFromIndexWithFileFallback(settings, fallbackSettings, indexConfigManager)) + .leftMap(toStartingFailure) } - runStartingFailureProgram(action) } private def loadRorTestConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - EitherT.right(Task.now(LoadedTestRorConfig(TestRorConfig.NotSet))) + EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(TestRorConfig.NotSet)) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => // todo: move // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - val action = LoadRawTestRorConfig.loadFromIndexWithFallback( - indexLoadingSettings = settings, - fallbackConfig = notSetTestRorConfig - ) - EitherT.right(runTestProgram(action)) - } - } - private def runStartingFailureProgram[A](action: LoadRorConfig[ErrorOr[A]]) = { - val compiler = RorConfigLoadingInterpreter.create(indexConfigManager) - EitherT(action.foldMap(compiler)) - .leftMap(toStartingFailure) + EitherT { + LoadRawTestRorConfig.loadFromIndexWithFallback( + indexLoadingSettings = settings, + fallbackConfig = notSetTestRorConfig, + indexTestConfigManager + ) + }.leftFlatMap { + case LoadedTestRorConfig.IndexParsingError(message) => + logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") + EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + case LoadedTestRorConfig.IndexUnknownStructure => + logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") + EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + case LoadedTestRorConfig.IndexNotExist => + logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") + EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + } + } } private def toStartingFailure(error: LoadedRorConfig.Error) = { @@ -130,23 +136,6 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def runTestProgram(action: LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]): Task[LoadedTestRorConfig[TestRorConfig]] = { - val compiler = TestRorConfigLoadingInterpreter.create(indexTestConfigManager) - EitherT(action.foldMap(compiler)) - .leftMap { - case LoadedTestRorConfig.IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - LoadedTestRorConfig(notSetTestRorConfig) - case LoadedTestRorConfig.IndexUnknownStructure => - logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - LoadedTestRorConfig(notSetTestRorConfig) - case LoadedTestRorConfig.IndexNotExist => - logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - LoadedTestRorConfig(notSetTestRorConfig) - } - .merge - } - private def startRor(esConfig: EsConfig, loadedConfig: LoadedRorConfig[RawRorConfig], loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala index 01aa137e8f..4af385735e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala @@ -16,32 +16,88 @@ */ package tech.beshu.ror.configuration -import cats.free.Free +import cats.data.EitherT +import cats.implicits.toShow +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} -import tech.beshu.ror.configuration.loader.LoadedRorConfig - -object RorConfigLoading { - type ErrorOr[A] = LoadedRorConfig.Error Either A - type IndexErrorOr[A] = LoadedRorConfig.LoadingIndexError Either A - type LoadRorConfig[A] = Free[LoadRorConfigAction, A] - - sealed trait LoadRorConfigAction[A] - object LoadRorConfigAction { - final case class ForceLoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadRorConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] - final case class LoadRorConfigFromFile(settings: LoadFromFileSettings) - extends LoadRorConfigAction[ErrorOr[LoadedRorConfig[RawRorConfig]]] - final case class LoadRorConfigFromIndex(settings: LoadFromIndexSettings) - extends LoadRorConfigAction[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] +import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} +import tech.beshu.ror.configuration.loader.LoadedRorConfig.IndexParsingError +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.{FileRorConfigLoader, LoadedRorConfig, RorConfigLoader} +import tech.beshu.ror.implicits.* + +object RorConfigLoading extends Logging { + + def loadRorConfigFromIndex(settings: LoadFromIndexSettings, indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error & LoadedRorConfig.LoadingIndexError, LoadedRorConfig[RawRorConfig]]] = { + val rorConfigIndex = settings.rorConfigIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") + EitherT { + indexConfigManager + .load(settings.rorConfigIndex) + .delayExecution(settings.loadingDelay.value.value) + }.map { rawRorConfig => + logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") + rawRorConfig + } + .bimap(convertIndexError, LoadedRorConfig.apply) + .leftMap { error => + logIndexLoadingError(error) + error + }.value + } + + def loadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) + logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") + EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + .bimap(convertFileError, LoadedRorConfig.apply) + .leftMap { error => + logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") + error + } + .value } - def loadRorConfigFromIndex(settings: LoadFromIndexSettings): LoadRorConfig[IndexErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadRorConfigAction.LoadRorConfigFromIndex(settings)) + def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) + logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") + EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + .bimap(convertFileError, LoadedRorConfig.apply) + .leftMap { error => + logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") + error + }.value + } +// Free.liftF(LoadRorConfigAction.ForceLoadRorConfigFromFile(settings)) + + private def convertFileError(error: RorConfigLoader.Error[FileRorConfigLoader.Error]): LoadedRorConfig.Error = { + error match { + case ParsingError(error) => + val show = error.show + LoadedRorConfig.FileParsingError(show) + case SpecializedError(FileRorConfigLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) + } + } - def loadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadRorConfigAction.LoadRorConfigFromFile(settings)) + private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]) = + error match { + case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) + case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedRorConfig.IndexNotExist + case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedRorConfig.IndexUnknownStructure + } - def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]] = - Free.liftF(LoadRorConfigAction.ForceLoadRorConfigFromFile(settings)) + private def logIndexLoadingError[A](error: LoadedRorConfig.LoadingIndexError): Unit = { + error match { + case IndexParsingError(message) => + logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") + case LoadedRorConfig.IndexUnknownStructure => + logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") + case LoadedRorConfig.IndexNotExist => + logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") + } + } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala index 43da273ed9..ed1f15abbf 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala @@ -16,21 +16,58 @@ */ package tech.beshu.ror.configuration -import cats.free.Free +import cats.data.EitherT +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings -import tech.beshu.ror.configuration.loader.LoadedTestRorConfig +import tech.beshu.ror.configuration.index.{IndexConfigError, IndexTestConfigManager} +import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.IndexParsingError +import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.{LoadedTestRorConfig, RorConfigLoader} +import tech.beshu.ror.implicits.* -object TestRorConfigLoading { - type IndexErrorOr[A] = LoadedTestRorConfig.LoadingIndexError Either A - type LoadTestRorConfig[A] = Free[LoadRorTestConfigAction, A] +object TestRorConfigLoading extends Logging { - sealed trait LoadRorTestConfigAction[A] - object LoadRorTestConfigAction { - final case class LoadTestRorConfigFromIndex(settings: LoadFromIndexSettings) - extends LoadRorTestConfigAction[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] + def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings, + indexConfigManager: IndexTestConfigManager): Task[Either[LoadedTestRorConfig.LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { + val rorConfigIndex = settings.rorConfigIndex + val loadingDelay = settings.loadingDelay + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") + EitherT { + indexConfigManager + .load(rorConfigIndex) + .delayExecution(loadingDelay.value.value) + }.map { testConfig => + testConfig match { + case TestRorConfig.Present(rawConfig, _, _) => + logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw test config from index: ${rawConfig.raw.show}") + case TestRorConfig.NotSet => + logger.debug("[CLUSTERWIDE SETTINGS] There was no test settings in index. Test settings engine will be not initialized.") + } + testConfig + } + .bimap(convertIndexError, LoadedTestRorConfig.apply) + .leftMap { error => + logIndexLoadingError(error) + error + }.value } - def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = - Free.liftF(LoadRorTestConfigAction.LoadTestRorConfigFromIndex(settings)) + private def logIndexLoadingError(error: LoadedTestRorConfig.LoadingIndexError): Unit = { + error match { + case IndexParsingError(message) => + logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") + case LoadedTestRorConfig.IndexUnknownStructure => + logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") + case LoadedTestRorConfig.IndexNotExist => + logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") + } + } + private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]): LoadedTestRorConfig.LoadingIndexError = + error match { + case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) + case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedTestRorConfig.IndexNotExist + case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedTestRorConfig.IndexUnknownStructure + } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index 46c6a80fd1..e8fdf4fda6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -16,70 +16,74 @@ */ package tech.beshu.ror.configuration.loader -import cats.free.Free +import monix.eval.Task import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.RorConfigLoading.* import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} +import tech.beshu.ror.configuration.index.IndexConfigManager import scala.concurrent.duration.DurationInt import scala.language.postfixOps object LoadRawRorConfig { - type LoadResult = ErrorOr[LoadedRorConfig[RawRorConfig]] - def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackFileLoadingSettings: LoadFromFileSettings): LoadRorConfig[LoadResult] = { + fallbackFileLoadingSettings: LoadFromFileSettings, + indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, - fallback = loadRorConfigFromFile(fallbackFileLoadingSettings) + fallback = loadRorConfigFromFile(fallbackFileLoadingSettings), + indexConfigManager ) } - def loadFromFile(settings: LoadFromFileSettings): LoadRorConfig[LoadResult] = { - for { - loadedConfig <- forceLoadRorConfigFromFile(settings) - } yield loadedConfig + def loadFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + forceLoadRorConfigFromFile(settings) } - def loadFromIndex(settings: LoadFromIndexSettings): LoadRorConfig[LoadResult] = { + def loadFromIndex(settings: LoadFromIndexSettings, indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { for { // todo: is the copy ok? - result <- loadRorConfigFromIndex(settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds))) + result <- loadRorConfigFromIndex( + settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)), + indexConfigManager + ) rawRorConfig <- result match { case Left(LoadedRorConfig.IndexNotExist) => - Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexNotExist)) + Task.now(Left(LoadedRorConfig.IndexNotExist: LoadedRorConfig.Error)) case Left(LoadedRorConfig.IndexUnknownStructure) => - Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) + Task.now(Left(LoadedRorConfig.IndexUnknownStructure: LoadedRorConfig.Error)) case Left(error@LoadedRorConfig.IndexParsingError(_)) => - Free.pure[LoadRorConfigAction, LoadResult](Left(error)) + Task.now(Left(error: LoadedRorConfig.Error)) case Right(value) => - Free.pure[LoadRorConfigAction, LoadResult](Right(value)) + Task.now(Right(value)) } } yield rawRorConfig } private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: LoadRorConfig[ErrorOr[LoadedRorConfig[RawRorConfig]]]): LoadRorConfig[LoadResult] = { + fallback: Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]], + indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { settings.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => for { - result <- loadRorConfigFromIndex(settings) + result <- loadRorConfigFromIndex(settings, indexConfigManager) rawRorConfig <- result match { case Left(LoadedRorConfig.IndexNotExist) => - Free.defer(attemptLoadingConfigFromIndex( + attemptLoadingConfigFromIndex( settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback - )) + fallback = fallback, + indexConfigManager + ) case Left(LoadedRorConfig.IndexUnknownStructure) => - Free.pure[LoadRorConfigAction, LoadResult](Left(LoadedRorConfig.IndexUnknownStructure)) + Task.now(Left(LoadedRorConfig.IndexUnknownStructure)) case Left(error@LoadedRorConfig.IndexParsingError(_)) => - Free.pure[LoadRorConfigAction, LoadResult](Left(error)) + Task.now(Left(error)) case Right(value) => - Free.pure[LoadRorConfigAction, LoadResult](Right(value)) + Task.now(Right(value)) } } yield rawRorConfig } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala index 64f8257fe8..01e9b29076 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala @@ -16,11 +16,13 @@ */ package tech.beshu.ror.configuration.loader -import cats.free.Free +import monix.eval.Task import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.TestRorConfig import tech.beshu.ror.configuration.TestRorConfigLoading.* +import tech.beshu.ror.configuration.index.IndexTestConfigManager +import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.LoadingIndexError import scala.concurrent.duration.DurationInt import scala.language.postfixOps @@ -28,35 +30,40 @@ import scala.language.postfixOps object LoadRawTestRorConfig { def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackConfig: TestRorConfig): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = { + fallbackConfig: TestRorConfig, + indexConfigManager: IndexTestConfigManager): Task[Either[LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, - fallback = fallbackConfig + fallback = fallbackConfig, + indexConfigManager ) } private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: TestRorConfig): LoadTestRorConfig[IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]] = { + fallback: TestRorConfig, + indexConfigManager: IndexTestConfigManager): Task[Either[LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { settings.loadingAttemptsCount.value.value match { case 0 => - Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]]( - Right(LoadedTestRorConfig[TestRorConfig](fallback)) - ) + Task.now(Right(LoadedTestRorConfig[TestRorConfig](fallback))) case attemptsCount => for { - result <- loadTestRorConfigFromIndex(settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds))) + result <- loadTestRorConfigFromIndex( + settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)), + indexConfigManager + ) rawRorConfig <- result match { case Left(LoadedTestRorConfig.IndexNotExist) => - Free.defer(attemptLoadingConfigFromIndex( + attemptLoadingConfigFromIndex( settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback - )) + fallback = fallback, + indexConfigManager + ) case Left(error@LoadedTestRorConfig.IndexUnknownStructure) => - Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) + Task.now(Left(error)) case Left(error@LoadedTestRorConfig.IndexParsingError(_)) => - Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Left(error)) + Task.now(Left(error)) case Right(value) => - Free.pure[LoadRorTestConfigAction, IndexErrorOr[LoadedTestRorConfig[TestRorConfig]]](Right(value)) + Task.now(Right(value)) } } yield rawRorConfig } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala deleted file mode 100644 index 2642ec489e..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoadingInterpreter.scala +++ /dev/null @@ -1,113 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader - -import cats.data.EitherT -import cats.~> -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError.* -import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction -import tech.beshu.ror.configuration.RorProperties.LoadingDelay -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} -import tech.beshu.ror.configuration.loader.LoadedRorConfig.* -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{RawRorConfigYamlParser, RorConfigLoading} -import tech.beshu.ror.implicits.* - -object RorConfigLoadingInterpreter extends Logging { - - def create(indexConfigManager: IndexConfigManager) - (implicit systemContext: SystemContext): LoadRorConfigAction ~> Task = new (LoadRorConfigAction ~> Task) { - override def apply[A](fa: LoadRorConfigAction[A]): Task[A] = fa match { - case RorConfigLoading.LoadRorConfigAction.ForceLoadRorConfigFromFile(settings) => - val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") - EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) - .bimap(convertFileError, LoadedRorConfig.apply) - .leftMap { error => - logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") - error - }.value - case RorConfigLoading.LoadRorConfigAction.LoadRorConfigFromFile(settings) => - val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) - .bimap(convertFileError, LoadedRorConfig.apply) - .leftMap { error => - logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") - error - } - .value - case RorConfigLoading.LoadRorConfigAction.LoadRorConfigFromIndex(settings) => - val rorConfigIndex = settings.rorConfigIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") - loadFromIndex(indexConfigManager, rorConfigIndex, settings.loadingDelay) - .map { rawRorConfig => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") - rawRorConfig - } - .bimap(convertIndexError, LoadedRorConfig.apply) - .leftMap { error => - logIndexLoadingError(error) - error - }.value - } - } - - private def logIndexLoadingError[A](error: LoadedRorConfig.LoadingIndexError): Unit = { - error match { - case IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedRorConfig.IndexUnknownStructure => - logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") - case LoadedRorConfig.IndexNotExist => - logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") - } - } - - private def loadFromIndex[A](indexConfigManager: IndexConfigManager, - index: RorConfigurationIndex, - loadingDelay: LoadingDelay) = { - EitherT { - indexConfigManager - .load(index) - .delayExecution(loadingDelay.value.value) - } - } - - private def convertFileError(error: RorConfigLoader.Error[FileRorConfigLoader.Error]): LoadedRorConfig.Error = { - error match { - case ParsingError(error) => - val show = error.show - LoadedRorConfig.FileParsingError(show) - case SpecializedError(FileRorConfigLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) - } - } - - private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError])= - error match { - case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) - case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedRorConfig.IndexNotExist - case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedRorConfig.IndexUnknownStructure - } - -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala deleted file mode 100644 index e7850e7805..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/TestRorConfigLoadingInterpreter.scala +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader - -import cats.data.EitherT -import cats.~> -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.RorProperties.LoadingDelay -import tech.beshu.ror.configuration.TestRorConfigLoading.LoadRorTestConfigAction -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexTestConfigManager} -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.* -import tech.beshu.ror.configuration.{TestRorConfig, TestRorConfigLoading} -import tech.beshu.ror.implicits.* - -object TestRorConfigLoadingInterpreter extends Logging { - - def create(indexConfigManager: IndexTestConfigManager): LoadRorTestConfigAction ~> Task = new (LoadRorTestConfigAction ~> Task) { - override def apply[A](fa: LoadRorTestConfigAction[A]): Task[A] = fa match { - case TestRorConfigLoading.LoadRorTestConfigAction.LoadTestRorConfigFromIndex(settings) => - val rorConfigIndex = settings.rorConfigIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") - loadFromIndex(indexConfigManager, rorConfigIndex, settings.loadingDelay) - .map { testConfig => - testConfig match { - case TestRorConfig.Present(rawConfig, _, _) => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw test config from index: ${rawConfig.raw.show}") - case TestRorConfig.NotSet => - logger.debug("[CLUSTERWIDE SETTINGS] There was no test settings in index. Test settings engine will be not initialized.") - } - testConfig - } - .bimap(convertIndexError, LoadedTestRorConfig.apply) - .leftMap { error => - logIndexLoadingError(error) - error - }.value - } - } - - private def logIndexLoadingError(error: LoadedTestRorConfig.LoadingIndexError): Unit = { - error match { - case IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedTestRorConfig.IndexUnknownStructure => - logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") - case LoadedTestRorConfig.IndexNotExist => - logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") - } - } - - private def loadFromIndex(indexConfigManager: IndexTestConfigManager, - index: RorConfigurationIndex, - loadingDelay: LoadingDelay) = { - EitherT { - indexConfigManager - .load(index) - .delayExecution(loadingDelay.value.value) - } - } - - private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]): LoadedTestRorConfig.LoadingIndexError = - error match { - case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) - case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedTestRorConfig.IndexNotExist - case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedTestRorConfig.IndexUnknownStructure - } - -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala index 1c7bf5923d..5b3d7f2b1b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala @@ -18,6 +18,7 @@ package tech.beshu.ror.configuration.loader import java.nio.file.Path +// todo: do we need this wrapper? final case class LoadedRorConfig[A](value: A) object LoadedRorConfig { From 1039fd1836c2cc48dba1053e3ca5add7cafe5754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 4 Jul 2025 16:01:56 +0200 Subject: [PATCH 009/103] refactoring --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 29 ++++++++++++------- .../tech/beshu/ror/boot/RorInstance.scala | 20 ++++++++++--- .../MainConfigBasedReloadableEngine.scala | 6 ++-- .../TestConfigBasedReloadableEngine.scala | 10 ++++--- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 48940ea945..3d7ef716ae 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -51,16 +51,17 @@ class ReadonlyRest(coreFactory: CoreFactory, (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { - private [boot] val indexConfigManager: IndexConfigManager = new IndexConfigManager(indexContentService, ???) - private [boot] val indexTestConfigManager: IndexTestConfigManager = new IndexTestConfigManager(indexContentService, ???) private [boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) def start(): Task[Either[StartingFailure, RorInstance]] = { (for { esConfig <- loadEsConfig() - loadedRorConfig <- loadRorConfig(esConfig) - loadedTestRorConfig <- loadRorTestConfig(esConfig) - instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig) + rorYamlParser = new RawRorConfigYamlParser(esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsMaxSize) + indexConfigManager = new IndexConfigManager(indexContentService, rorYamlParser) + indexTestConfigManager = new IndexTestConfigManager(indexContentService, rorYamlParser) + loadedRorConfig <- loadRorConfig(esConfig, indexConfigManager) + loadedTestRorConfig <- loadRorTestConfig(esConfig, indexTestConfigManager) + instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig, indexConfigManager, indexTestConfigManager) } yield instance).value } @@ -76,7 +77,8 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadRorConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedRorConfig[RawRorConfig]] = { + private def loadRorConfig(esConfig: EsConfig, + indexConfigManager: IndexConfigManager): EitherT[Task, StartingFailure, LoadedRorConfig[RawRorConfig]] = { esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => EitherT(LoadRawRorConfig.loadFromFile(settings)) @@ -91,7 +93,8 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadRorTestConfig(esConfig: EsConfig): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { + private def loadRorTestConfig(esConfig: EsConfig, + indexTestConfigManager: IndexTestConfigManager): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(TestRorConfig.NotSet)) @@ -138,11 +141,13 @@ class ReadonlyRest(coreFactory: CoreFactory, private def startRor(esConfig: EsConfig, loadedConfig: LoadedRorConfig[RawRorConfig], - loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { + loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig], + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager) = { for { mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorEsLevelSettings.rorConfigIndex)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) - rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, loadedConfig) + rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedConfig) } yield rorInstance } @@ -190,6 +195,8 @@ class ReadonlyRest(coreFactory: CoreFactory, private def createRorInstance(esConfig: EsConfig, engine: Engine, testEngine: TestEngine, + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager, loadedConfig: LoadedRorConfig[RawRorConfig]) = { EitherT.right[StartingFailure] { val rorSettingsFile = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile @@ -197,9 +204,9 @@ class ReadonlyRest(coreFactory: CoreFactory, val rorConfigIndex = esConfig.rorEsLevelSettings.rorConfigIndex esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index b0e622aa34..62332ab642 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -32,7 +32,7 @@ import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} import tech.beshu.ror.boot.engines.{Engines, MainConfigBasedReloadableEngine, TestConfigBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.index.{IndexConfigError, SavingIndexConfigError} +import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager, IndexTestConfigManager, SavingIndexConfigError} import tech.beshu.ror.configuration.loader.RorConfigLoader.Error import tech.beshu.ror.configuration.loader.FileRorConfigLoader import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser, RorConfig} @@ -47,6 +47,8 @@ class RorInstance private(boot: ReadonlyRest, mainReloadInProgress: Semaphore[Task], initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager, rorSettingsIndex: RorConfigurationIndex, rorSettingsFile: File, rorSettingsMaxSize: Information) @@ -70,12 +72,14 @@ class RorInstance private(boot: ReadonlyRest, boot, (initialEngine.engine, initialEngine.config), mainReloadInProgress, + indexConfigManager, rorSettingsIndex, ) private val anTestConfigEngine = TestConfigBasedReloadableEngine.create( boot, initialTestEngine, testReloadInProgress, + indexTestConfigManager, rorSettingsIndex ) @@ -84,7 +88,7 @@ class RorInstance private(boot: ReadonlyRest, private val configRestApi = new ConfigApi( rorInstance = this, rarRorConfigYamlParser, - boot.indexConfigManager, + indexConfigManager, new FileRorConfigLoader(rorSettingsFile, rarRorConfigYamlParser), rorSettingsIndex ) @@ -270,30 +274,36 @@ object RorInstance { def createWithPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager, refreshInterval: RefreshInterval, rorSettingsFile: File, rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) + create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager, rorSettingsFile: File, rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) + create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) } private def create(boot: ReadonlyRest, mode: RorInstance.Mode, engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, + indexConfigManager: IndexConfigManager, + indexTestConfigManager: IndexTestConfigManager, rorSettingsFile: File, rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) @@ -309,6 +319,8 @@ object RorInstance { mainReloadInProgress = isReloadInProgressSemaphore, initialTestEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, + indexConfigManager = indexConfigManager, + indexTestConfigManager = indexTestConfigManager, rorSettingsIndex = rorSettingsIndex, rorSettingsFile = rorSettingsFile, rorSettingsMaxSize = rorSettingsMaxSize diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala index c3ec1789a9..d7519d4f62 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala @@ -33,12 +33,14 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.ConfigHash.* import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.index.IndexConfigManager import tech.beshu.ror.configuration.index.SavingIndexConfigError.CannotSaveConfig import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, initialEngine: (Engine, RawRorConfig), reloadInProgress: Semaphore[Task], + indexConfigManager: IndexConfigManager, rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) @@ -122,12 +124,12 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, private def saveConfig(newConfig: RawRorConfig): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { for { - saveResult <- boot.indexConfigManager.save(newConfig, rorConfigurationIndex) + saveResult <- indexConfigManager.save(newConfig, rorConfigurationIndex) } yield saveResult.left.map(IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply) } private def loadRorConfigFromIndex() = { - boot.indexConfigManager + indexConfigManager .load(rorConfigurationIndex) .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala index d7fd925279..92128dc6dc 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpirationConfig, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.ConfigHash.* import tech.beshu.ror.configuration.TestRorConfig.Present.ExpirationConfig -import tech.beshu.ror.configuration.index.SavingIndexConfigError +import tech.beshu.ror.configuration.index.{IndexTestConfigManager, SavingIndexConfigError} import tech.beshu.ror.configuration.{RawRorConfig, TestRorConfig} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value @@ -41,6 +41,7 @@ import tech.beshu.ror.utils.ScalaOps.value private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], + indexTestConfigManager: IndexTestConfigManager, rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) @@ -184,7 +185,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, private def saveConfigInIndex[A](newConfig: TestRorConfig.Present, onFailure: SavingIndexConfigError => A): EitherT[Task, A, Unit] = { - EitherT(boot.indexTestConfigManager.save(newConfig, rorConfigurationIndex)) + EitherT(indexTestConfigManager.save(newConfig, rorConfigurationIndex)) .leftMap(onFailure) } @@ -209,7 +210,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, } private def loadRorConfigFromIndex(): EitherT[Task, IndexConfigReloadError, TestRorConfig] = EitherT { - boot.indexTestConfigManager + indexTestConfigManager .load(rorConfigurationIndex) .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) } @@ -237,6 +238,7 @@ object TestConfigBasedReloadableEngine { def create(boot: ReadonlyRest, initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], + indexTestConfigManager: IndexTestConfigManager, rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): TestConfigBasedReloadableEngine = { @@ -248,7 +250,7 @@ object TestConfigBasedReloadableEngine { case TestEngine.Invalidated(config, expiration) => InitialEngine.Invalidated(config, expirationConfig(expiration)) } - new TestConfigBasedReloadableEngine(boot, engine, reloadInProgress, rorConfigurationIndex) + new TestConfigBasedReloadableEngine(boot, engine, reloadInProgress, indexTestConfigManager, rorConfigurationIndex) } private def expirationConfig(config: TestEngine.Expiration) = EngineExpirationConfig(config.ttl, config.validTo) From 0b54376ef6091c9acf9b343bc9cd97734e3bb20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 8 Jul 2025 10:59:53 +0200 Subject: [PATCH 010/103] refactoring --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 52 +++---- .../SecurityProviderConfiguratorForFips.scala | 22 ++- ...g.scala => EsConfigBasedRorSettings.scala} | 136 +++++++----------- .../ror/configuration/FipsConfiguration.scala | 95 ------------ .../configuration/ReadonlyRestEsConfig.scala | 43 ------ ...figuration.scala => RorBootSettings.scala} | 26 ++-- .../beshu/ror/configuration/RorConfig.scala | 1 + .../ror/configuration/RorConfigLoading.scala | 2 +- .../ror/configuration/SslConfiguration.scala | 116 +++++++++++---- .../configuration/TestRorConfigLoading.scala | 2 +- .../loader/LoadRawRorConfig.scala | 2 +- .../loader/LoadRawTestRorConfig.scala | 2 +- .../main/scala/tech/beshu/ror/implicits.scala | 14 +- ...onTest.scala => RorBootSettingsTest.scala} | 22 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 9 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 47 +++--- .../RorNotAvailableRequestHandler.scala | 10 +- 17 files changed, 248 insertions(+), 353 deletions(-) rename core/src/main/scala/tech/beshu/ror/configuration/{EsConfig.scala => EsConfigBasedRorSettings.scala} (55%) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala rename core/src/main/scala/tech/beshu/ror/configuration/{RorBootConfiguration.scala => RorBootSettings.scala} (79%) rename core/src/test/scala/tech/beshu/ror/unit/configuration/{RorBootConfigurationTest.scala => RorBootSettingsTest.scala} (86%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 3d7ef716ae..bebc47f083 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,8 +34,7 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} @@ -53,33 +52,24 @@ class ReadonlyRest(coreFactory: CoreFactory, private [boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) - def start(): Task[Either[StartingFailure, RorInstance]] = { + def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - esConfig <- loadEsConfig() - rorYamlParser = new RawRorConfigYamlParser(esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsMaxSize) - indexConfigManager = new IndexConfigManager(indexContentService, rorYamlParser) - indexTestConfigManager = new IndexTestConfigManager(indexContentService, rorYamlParser) + rorYamlParser <- lift(new RawRorConfigYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) + indexConfigManager <- lift(new IndexConfigManager(indexContentService, rorYamlParser)) + indexTestConfigManager <- lift(new IndexTestConfigManager(indexContentService, rorYamlParser)) loadedRorConfig <- loadRorConfig(esConfig, indexConfigManager) loadedTestRorConfig <- loadRorTestConfig(esConfig, indexTestConfigManager) instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig, indexConfigManager, indexTestConfigManager) } yield instance).value } - private def loadEsConfig() = { - EitherT(EsConfig.from(esEnv)) - .leftMap { - case LoadEsConfigError.FileNotFound(file) => - StartingFailure(s"Cannot find elasticsearch settings file: [${file.show}]") - case LoadEsConfigError.MalformedContent(file, message) => - StartingFailure(s"Settings file is malformed: [${file.show}], ${message.show}") - case LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled(typeOfConfiguration) => - StartingFailure(s"Cannot use ROR ${typeOfConfiguration.show} when XPack Security is enabled") - } + private def lift[A](value: => A) = { + EitherT.liftF(Task.delay(value)) } - private def loadRorConfig(esConfig: EsConfig, + private def loadRorConfig(esConfig: EsConfigBasedRorSettings, indexConfigManager: IndexConfigManager): EitherT[Task, StartingFailure, LoadedRorConfig[RawRorConfig]] = { - esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => EitherT(LoadRawRorConfig.loadFromFile(settings)) .leftMap(toStartingFailure) @@ -93,9 +83,9 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadRorTestConfig(esConfig: EsConfig, + private def loadRorTestConfig(esConfig: EsConfigBasedRorSettings, indexTestConfigManager: IndexTestConfigManager): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { - esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(TestRorConfig.NotSet)) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => @@ -139,19 +129,19 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def startRor(esConfig: EsConfig, + private def startRor(esConfig: EsConfigBasedRorSettings, loadedConfig: LoadedRorConfig[RawRorConfig], loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig], indexConfigManager: IndexConfigManager, indexTestConfigManager: IndexTestConfigManager) = { for { - mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorEsLevelSettings.rorConfigIndex)) + mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorConfigIndex)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedConfig) } yield rorInstance } - private def loadTestEngine(esConfig: EsConfig, loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { + private def loadTestEngine(esConfig: EsConfigBasedRorSettings, loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { loadedTestRorConfig.value match { case TestRorConfig.NotSet => Task.now(TestEngine.NotConfigured) @@ -162,10 +152,10 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadActiveTestEngine(esConfig: EsConfig, testConfig: TestRorConfig.Present) = { + private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testConfig: TestRorConfig.Present) = { for { _ <- Task.delay(authServicesMocksProvider.update(testConfig.mocks)) - testEngine <- loadRorCore(testConfig.rawConfig, esConfig.rorEsLevelSettings.rorConfigIndex) + testEngine <- loadRorCore(testConfig.rawConfig, esConfig.rorConfigIndex) .map { case Right(loadedEngine) => TestEngine.Configured( @@ -192,17 +182,17 @@ class ReadonlyRest(coreFactory: CoreFactory, TestEngine.Expiration(config.ttl, config.validTo) } - private def createRorInstance(esConfig: EsConfig, + private def createRorInstance(esConfig: EsConfigBasedRorSettings, engine: Engine, testEngine: TestEngine, indexConfigManager: IndexConfigManager, indexTestConfigManager: IndexTestConfigManager, loadedConfig: LoadedRorConfig[RawRorConfig]) = { EitherT.right[StartingFailure] { - val rorSettingsFile = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsFile - val rorSettingsMaxSize = esConfig.rorEsLevelSettings.loadingRorCoreStrategy.rorSettingsMaxSize - val rorConfigIndex = esConfig.rorEsLevelSettings.rorConfigIndex - esConfig.rorEsLevelSettings.loadingRorCoreStrategy match { + val rorSettingsFile = esConfig.loadingRorCoreStrategy.rorSettingsFile + val rorSettingsMaxSize = esConfig.loadingRorCoreStrategy.rorSettingsMaxSize + val rorConfigIndex = esConfig.rorConfigIndex + esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => diff --git a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala index 0c1fc7e5e2..56b6220d01 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala @@ -18,22 +18,30 @@ package tech.beshu.ror.boot import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider -import tech.beshu.ror.configuration.FipsConfiguration -import tech.beshu.ror.configuration.FipsConfiguration.FipsMode +import tech.beshu.ror.configuration.RorSsl +import tech.beshu.ror.configuration.SslConfiguration.FipsMode.{NonFips, SslOnly} import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import java.security.Security object SecurityProviderConfiguratorForFips { - def configureIfRequired(fipsConfiguration: FipsConfiguration): Unit = { - fipsConfiguration.fipsMode match { - case FipsMode.SslOnly => + def configureIfRequired(ssl: RorSsl): Unit = { + val fipsModes = ssl match { + case RorSsl.OnlyExternalSslConfiguration(ssl) => ssl.fipsMode :: Nil + case RorSsl.OnlyInternodeSslConfiguration(ssl) => ssl.fipsMode :: Nil + case RorSsl.ExternalAndInternodeSslConfiguration(external, internode) => external.fipsMode :: internode.fipsMode :: Nil + } + fipsModes + .find { + case SslOnly => true + case NonFips => false + } + .foreach { _ => doPrivileged { Security.insertProviderAt(new BouncyCastleFipsProvider(), 1) // basic encryption provider Security.insertProviderAt(new BouncyCastleJsseProvider("fips:BCFIPS"), 2) // tls } - case FipsMode.NonFips => - } + } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala similarity index 55% rename from core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala rename to core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index ae2bb11bc1..821505866d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -25,34 +25,28 @@ import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadingRorCoreStrategy} -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} -import tech.beshu.ror.configuration.FipsConfiguration.FipsMode +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.language.implicitConversions -final case class EsConfig(rorEsLevelSettings: RorEsLevelSettings) +final case class EsConfigBasedRorSettings(boot: RorBootSettings, + ssl: Option[RorSsl], + rorConfigIndex: RorConfigurationIndex, + loadingRorCoreStrategy: LoadingRorCoreStrategy) -object EsConfig { +object EsConfigBasedRorSettings { def from(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[LoadEsConfigError, EsConfig]] = { + (implicit systemContext: SystemContext): Task[Either[LoadEsConfigError, EsConfigBasedRorSettings]] = { val configFile = esEnv.elasticsearchConfig - (for { + val result = for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) - rorEsLevelSettings <- loadRorEsLevelSettings(esEnv) - } yield EsConfig(rorEsLevelSettings)).value - } - - private def loadRorEsLevelSettings(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { - for { + bootSettings <- loadRorBootSettings(esEnv) loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex xpackSettings <- loadXpackSettings(esEnv, esEnv.isOssDistribution) @@ -60,9 +54,15 @@ object EsConfig { case ForceLoadingFromFile(settings) => settings case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings } - sslSettings <- loadSslSettings(esEnv, rorFileSettings, xpackSettings) - fibsConfiguration <- loadFipsConfiguration(esEnv, rorFileSettings, xpackSettings) - } yield RorEsLevelSettings(rorIndex, loadingRorCoreStrategy, sslSettings, fibsConfiguration) + sslSettings <- loadSslSettings(esEnv, rorFileSettings, xpackSettings) + } yield EsConfigBasedRorSettings(bootSettings, sslSettings, rorIndex, loadingRorCoreStrategy) + result.value + } + + private def loadRorBootSettings(esEnv: EsEnv) + (implicit systemContext: SystemContext) = { + EitherT(RorBootSettings.load(esEnv)) + .leftMap(error => MalformedContent(esEnv.configPath, error.message)) } private def loadXpackSettings(esEnv: EsEnv, ossDistribution: Boolean) @@ -76,29 +76,14 @@ object EsConfig { } private def loadSslSettings(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) - (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, RorSsl] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, Option[RorSsl]] = { EitherT(RorSsl.load(esEnv, rorFileSettings)) .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) - .subflatMap { rorSsl => - if (rorSsl != RorSsl.noSsl && xpackSettings.securityEnabled) { - Left(RorSettingsInactiveWhenXpackSecurityIsEnabled(SettingsType.Ssl)) - } else { + .subflatMap { + case Some(ssl) if xpackSettings.securityEnabled => + Left(RorSettingsInactiveWhenXpackSecurityIsEnabled) + case rorSsl@(Some(_) | None) => Right(rorSsl) - } - } - } - - private def loadFipsConfiguration(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) - (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, FipsConfiguration] = { - EitherT(FipsConfiguration.load(esEnv, rorFileSettings)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) - .subflatMap { fipsConfiguration => - fipsConfiguration.fipsMode match { - case FipsMode.SslOnly if xpackSettings.securityEnabled => - Left(RorSettingsInactiveWhenXpackSecurityIsEnabled(SettingsType.Fips)) - case FipsMode.NonFips | FipsMode.SslOnly => - Right(fipsConfiguration) - } } } @@ -118,53 +103,42 @@ object EsConfig { } } - final case class RorEsLevelSettings(rorConfigIndex: RorConfigurationIndex, - loadingRorCoreStrategy: LoadingRorCoreStrategy, - ssl: RorSsl, - fipsConfiguration: FipsConfiguration) - object RorEsLevelSettings { - sealed trait LoadingRorCoreStrategy - object LoadingRorCoreStrategy { - final case class ForceLoadingFromFile(settings: LoadFromFileSettings) extends LoadingRorCoreStrategy - final case class LoadFromIndexWithFileFallback(settings: LoadFromIndexSettings, - fallbackSettings: LoadFromFileSettings) - extends LoadingRorCoreStrategy - } + sealed trait LoadingRorCoreStrategy + object LoadingRorCoreStrategy { + final case class ForceLoadingFromFile(settings: LoadFromFileSettings) extends LoadingRorCoreStrategy + final case class LoadFromIndexWithFileFallback(settings: LoadFromIndexSettings, + fallbackSettings: LoadFromFileSettings) + extends LoadingRorCoreStrategy + } - implicit class FromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { - def rorSettingsFile: File = strategy match { - case ForceLoadingFromFile(settings) => settings.rorSettingsFile - case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings.rorSettingsFile - } - def rorSettingsMaxSize: Information = strategy match { - case ForceLoadingFromFile(settings) => settings.settingsMaxSize - case LoadFromIndexWithFileFallback(settings, _) => settings.settingsMaxSize - } + implicit class FromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { + def rorSettingsFile: File = strategy match { + case ForceLoadingFromFile(settings) => settings.rorSettingsFile + case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings.rorSettingsFile } - final case class LoadFromFileSettings(rorSettingsFile: File, - settingsMaxSize: Information) - final case class LoadFromIndexSettings(rorConfigIndex: RorConfigurationIndex, - refreshInterval: RefreshInterval, - loadingAttemptsInterval: LoadingAttemptsInterval, - loadingAttemptsCount: LoadingAttemptsCount, - loadingDelay: LoadingDelay, - settingsMaxSize: Information) + def rorSettingsMaxSize: Information = strategy match { + case ForceLoadingFromFile(settings) => settings.settingsMaxSize + case LoadFromIndexWithFileFallback(settings, _) => settings.settingsMaxSize + } } + + final case class LoadFromFileSettings(rorSettingsFile: File, + settingsMaxSize: Information) + final case class LoadFromIndexSettings(rorConfigIndex: RorConfigurationIndex, + refreshInterval: RefreshInterval, + loadingAttemptsInterval: LoadingAttemptsInterval, + loadingAttemptsCount: LoadingAttemptsCount, + loadingDelay: LoadingDelay, + settingsMaxSize: Information) + private final case class XpackSettings(securityEnabled: Boolean) sealed trait LoadEsConfigError object LoadEsConfigError { final case class FileNotFound(file: File) extends LoadEsConfigError final case class MalformedContent(file: File, message: String) extends LoadEsConfigError - final case class RorSettingsInactiveWhenXpackSecurityIsEnabled(settingsType: SettingsType) extends LoadEsConfigError - object RorSettingsInactiveWhenXpackSecurityIsEnabled { - sealed trait SettingsType - object SettingsType { - case object Ssl extends SettingsType - case object Fips extends SettingsType - } - } + case object RorSettingsInactiveWhenXpackSecurityIsEnabled extends LoadEsConfigError } private object decoders { @@ -209,10 +183,10 @@ object EsConfig { } } -// private implicit val loadFromFileSettingsDecoder: Decoder[LoadFromFileSettings] = { -// //YamlKeyDecoder[String](path = NonEmptyList.of("readonlyrest", "settings", "file", "path")) -// ??? -// } + // private implicit val loadFromFileSettingsDecoder: Decoder[LoadFromFileSettings] = { + // //YamlKeyDecoder[String](path = NonEmptyList.of("readonlyrest", "settings", "file", "path")) + // ??? + // } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala deleted file mode 100644 index cef0eddc71..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/FipsConfiguration.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import better.files.File -import io.circe.Decoder -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings -import tech.beshu.ror.configuration.FipsConfiguration.FipsMode -import tech.beshu.ror.configuration.FipsConfiguration.FipsMode.NonFips -import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.implicits.* - -final case class FipsConfiguration(fipsMode: FipsMode) - -object FipsConfiguration extends Logging { - - def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, FipsConfiguration]] = Task { - val esConfig = esEnv.elasticsearchConfig - loadFipsConfigFromFile(esConfig) - .fold( - error => Left(error), - { - case FipsConfiguration(FipsMode.NonFips) => - logger.info(s"Cannot find FIPS configuration in ${esConfig.show} ...") - fallbackToRorConfig(loadRorFromFileSettings.rorSettingsFile) - case ssl => - Right(ssl) - } - ) - } - - private def loadFipsConfigFromFile(configFile: File) - (implicit systemContext: SystemContext): Either[MalformedSettings, FipsConfiguration] = { - new YamlFileBasedConfigLoader(configFile).loadConfig[FipsConfiguration](configName = "ROR FIPS Settings") - } - - private def fallbackToRorConfig(rorSettingsFile: File) - (implicit systemContext: SystemContext) = { - logger.info(s"... trying: ${rorSettingsFile.show}") - if (rorSettingsFile.exists) { - loadFipsConfigFromFile(rorSettingsFile) - } else { - Right(FipsConfiguration(FipsMode.NonFips)) - } - } - - private implicit val fipsModeDecoder: Decoder[FipsMode] = { - Decoder.decodeString.emap { - case "NON_FIPS" => Right(FipsMode.NonFips) - case "SSL_ONLY" => Right(FipsMode.SslOnly) - case _ => Left("Invalid configuration option for FIPS MODE. Valid values are: NON_FIPS, SSL_ONLY") - } - } - - private implicit val fipsConfigurationDecoder: Decoder[FipsConfiguration] = { - Decoder.instance { c => - c.downField("readonlyrest") - .getOrElse[FipsMode]("fips_mode")(FipsMode.NonFips) - .map(FipsConfiguration(_)) - } - } - - sealed trait FipsMode - object FipsMode { - case object NonFips extends FipsMode - case object SslOnly extends FipsMode - } - - implicit class FipsConfigurationOps(fipsConfiguration: FipsConfiguration) { - def isSslFipsCompliant: Boolean = { - fipsConfiguration.fipsMode match { - case NonFips => false - case _ => true - } - } - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala deleted file mode 100644 index df260cc178..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/ReadonlyRestEsConfig.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import cats.data.EitherT -import monix.eval.Task -import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings -import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.utils.ScalaOps.* - -final case class ReadonlyRestEsConfig(bootConfig: RorBootConfiguration, - sslConfig: RorSsl, - fipsConfig: FipsConfiguration) - -object ReadonlyRestEsConfig { - - // todo: do we need it? - def load(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, ReadonlyRestEsConfig]] = { - value { - for { - bootConfig <- EitherT(RorBootConfiguration.load(esEnv)) - sslConfig <- EitherT(RorSsl.load(esEnv, rorFileSettings)) - fipsConfig <- EitherT(FipsConfiguration.load(esEnv, rorFileSettings)) - } yield ReadonlyRestEsConfig(bootConfig, sslConfig, fipsConfig) - } - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala similarity index 79% rename from core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala rename to core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala index 79093ae307..e49ff5746e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala @@ -22,26 +22,26 @@ import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlKeyDecoder -final case class RorBootConfiguration(rorNotStartedResponse: RorNotStartedResponse, - rorFailedToStartResponse: RorFailedToStartResponse) +final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, + rorFailedToStartResponse: RorFailedToStartResponse) -object RorBootConfiguration extends Logging { +object RorBootSettings extends Logging { def load(env: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootConfiguration]] = Task { - implicit val rorBootConfigurationDecoder: Decoder[RorBootConfiguration] = Decoders.decoder - loadRorBootstrapConfig(env.elasticsearchConfig) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootSettings]] = Task { + implicit val rorBootConfigurationDecoder: Decoder[RorBootSettings] = Decoders.decoder + loadRorBootstrapSettings(env.elasticsearchConfig) } - private def loadRorBootstrapConfig(configFile: File) - (implicit decoder: Decoder[RorBootConfiguration], - systemContext: SystemContext) = { - new YamlFileBasedConfigLoader(configFile).loadConfig[RorBootConfiguration](configName = "ROR boot configuration") + private def loadRorBootstrapSettings(configFile: File) + (implicit decoder: Decoder[RorBootSettings], + systemContext: SystemContext) = { + new YamlFileBasedConfigLoader(configFile).loadConfig[RorBootSettings](configName = "ROR boot settings") } final case class RorNotStartedResponse(httpCode: RorNotStartedResponse.HttpCode) @@ -71,11 +71,11 @@ private object Decoders extends Logging { val rorFailedTpStartResponseCode = "failed_to_start_response_code" } - def decoder: Decoder[RorBootConfiguration] = Decoder.instance { c => + def decoder: Decoder[RorBootSettings] = Decoder.instance { c => for { notStarted <- c.as[RorNotStartedResponse] failedToStart <- c.as[RorFailedToStartResponse] - } yield RorBootConfiguration(notStarted, failedToStart) + } yield RorBootSettings(notStarted, failedToStart) } private implicit val rorNotStartedResponseDecoder: Decoder[RorNotStartedResponse] = { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala index 469a5898dd..244193c748 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala @@ -25,6 +25,7 @@ import tech.beshu.ror.configuration.RorConfig.ImpersonationWarningsReader import scala.annotation.unused +// todo: rename final case class RorConfig(services: RorConfig.Services, localUsers: LocalUsers, impersonationWarningsReader: ImpersonationWarningsReader, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala index 4af385735e..f00e197d48 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala @@ -20,7 +20,7 @@ import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} import tech.beshu.ror.configuration.loader.LoadedRorConfig.IndexParsingError import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 875d97c808..a3657a07d3 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -22,8 +22,8 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromFileSettings -import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslConfiguration, InternodeSslConfiguration} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromFileSettings +import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslConfiguration, FipsMode, InternodeSslConfiguration} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.SSLCertHelper @@ -31,55 +31,84 @@ import tech.beshu.ror.utils.SSLCertHelper import java.io.File as JFile import java.nio.file.{Path, Paths} -final case class RorSsl(externalSsl: Option[ExternalSslConfiguration], - interNodeSsl: Option[InternodeSslConfiguration]) - +sealed trait RorSsl object RorSsl extends Logging { - val noSsl: RorSsl = RorSsl(None, None) + final case class OnlyExternalSslConfiguration(ssl: ExternalSslConfiguration) extends RorSsl + final case class OnlyInternodeSslConfiguration(ssl: InternodeSslConfiguration) extends RorSsl + final case class ExternalAndInternodeSslConfiguration(external: ExternalSslConfiguration, + internode: InternodeSslConfiguration) extends RorSsl + + implicit class ExtractSsl(val rorSsl: RorSsl) extends AnyVal { + def externalSsl: Option[ExternalSslConfiguration] = rorSsl match { + case OnlyExternalSslConfiguration(ssl) => Some(ssl) + case OnlyInternodeSslConfiguration(_) => None + case ExternalAndInternodeSslConfiguration(ssl, _) => Some(ssl) + } + + def internodeSsl: Option[InternodeSslConfiguration] = rorSsl match { + case OnlyExternalSslConfiguration(_) => None + case OnlyInternodeSslConfiguration(ssl) => Some(ssl) + case ExternalAndInternodeSslConfiguration(_, ssl) => Some(ssl) + } + } + + implicit class IsSslFipsCompliant(val fipsMode: FipsMode) extends AnyVal { + def isSslFipsCompliant: Boolean = fipsMode match { + case FipsMode.NonFips => false + case FipsMode.SslOnly => true + } + } def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorSsl]] = Task { - implicit val sslDecoder: Decoder[RorSsl] = SslDecoders.rorSslDecoder(esEnv.configPath) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSsl]]] = Task { + implicit val sslDecoder: Decoder[Option[RorSsl]] = SslDecoders.rorSslDecoder(esEnv.configPath) val esConfigFile = esEnv.elasticsearchConfig loadSslConfigFromFile(esConfigFile) .fold( error => Left(error), { - case RorSsl(None, None) => + case None => logger.info(s"Cannot find SSL configuration in ${esConfigFile.show} ...") fallbackToRorConfig(loadRorFromFileSettings.rorSettingsFile) - case ssl => - Right(ssl) + case Some(ssl) => + Right(Some(ssl)) } ) } private def fallbackToRorConfig(rorSettingsFile: File) - (implicit rorSslDecoder: Decoder[RorSsl], + (implicit rorSslDecoder: Decoder[Option[RorSsl]], systemContext: SystemContext) = { logger.info(s"... trying: ${rorSettingsFile.show}") if (rorSettingsFile.exists) { loadSslConfigFromFile(rorSettingsFile) } else { - Right(RorSsl.noSsl) + Right(None) } } private def loadSslConfigFromFile(configFile: File) - (implicit rorSslDecoder: Decoder[RorSsl], + (implicit rorSslDecoder: Decoder[Option[RorSsl]], systemContext: SystemContext) = { - new YamlFileBasedConfigLoader(configFile).loadConfig[RorSsl](configName = "ROR SSL settings") + new YamlFileBasedConfigLoader(configFile).loadConfig[Option[RorSsl]](configName = "ROR SSL settings") } } sealed trait SslConfiguration { def serverCertificateConfiguration: SslConfiguration.ServerCertificateConfiguration + def clientCertificateConfiguration: Option[SslConfiguration.ClientCertificateConfiguration] + def allowedProtocols: Set[SslConfiguration.Protocol] + def allowedCiphers: Set[SslConfiguration.Cipher] + def clientAuthenticationEnabled: Boolean + def certificateVerificationEnabled: Boolean + + def fipsMode: FipsMode } object SslConfiguration { @@ -117,7 +146,8 @@ object SslConfiguration { clientCertificateConfiguration: Option[ClientCertificateConfiguration], allowedProtocols: Set[SslConfiguration.Protocol], allowedCiphers: Set[SslConfiguration.Cipher], - clientAuthenticationEnabled: Boolean) + clientAuthenticationEnabled: Boolean, + fipsMode: FipsMode) extends SslConfiguration { val certificateVerificationEnabled: Boolean = false @@ -129,15 +159,25 @@ object SslConfiguration { allowedCiphers: Set[SslConfiguration.Cipher], clientAuthenticationEnabled: Boolean, certificateVerificationEnabled: Boolean, - hostnameVerificationEnabled: Boolean) + hostnameVerificationEnabled: Boolean, + fipsMode: FipsMode) extends SslConfiguration + + sealed trait FipsMode + object FipsMode { + case object NonFips extends FipsMode + case object SslOnly extends FipsMode + } + } private object SslDecoders extends Logging { + import tech.beshu.ror.configuration.SslConfiguration.* object consts { val rorSection = "readonlyrest" + val fipsMode = "fips_mode" val externalSsl = "ssl" val internodeSsl = "ssl_internode" val keystoreFile = "keystore_file" @@ -164,7 +204,6 @@ private object SslDecoders extends Logging { allowedCiphers: Set[SslConfiguration.Cipher], clientAuthentication: Option[Boolean]) - private implicit val keystorePasswordDecoder: Decoder[KeystorePassword] = DecoderHelpers.decodeStringLike.map(KeystorePassword.apply) private implicit val truststorePasswordDecoder: Decoder[TruststorePassword] = DecoderHelpers.decodeStringLike.map(TruststorePassword.apply) private implicit val keyPassDecoder: Decoder[KeyPass] = DecoderHelpers.decodeStringLike.map(KeyPass.apply) @@ -242,16 +281,34 @@ private object SslDecoders extends Logging { } } - def rorSslDecoder(basePath: Path): Decoder[RorSsl] = Decoder.instance { c => - implicit val internodeSslConfigDecoder: Decoder[Option[InternodeSslConfiguration]] = sslInternodeConfigurationDecoder(basePath) - implicit val externalSslConfigDecoder: Decoder[Option[ExternalSslConfiguration]] = sslExternalConfigurationDecoder(basePath) + def rorSslDecoder(basePath: Path): Decoder[Option[RorSsl]] = Decoder.instance { c => + implicit val isFipsCompliantDecoder: Decoder[FipsMode] = Decoder.decodeString.emap { + case "NON_FIPS" => Right(FipsMode.NonFips) + case "SSL_ONLY" => Right(FipsMode.SslOnly) + case _ => Left("Invalid configuration option for FIPS MODE. Valid values are: NON_FIPS, SSL_ONLY") + } for { - interNodeSsl <- c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslConfiguration]]] - externalSsl <- c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslConfiguration]]] - } yield RorSsl(externalSsl.flatten, interNodeSsl.flatten) + fipsMode <- c.downField(consts.rorSection).downField(consts.fipsMode).as[Option[FipsMode]] + interNodeSsl <- { + implicit val internodeSslConfigDecoder = sslInternodeConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslConfiguration]]] + } + externalSsl <- { + implicit val externalSslConfigDecoder = sslExternalConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslConfiguration]]] + } + } yield { + (externalSsl.flatten, interNodeSsl.flatten) match { + case (Some(ssl), None) => Some(RorSsl.OnlyExternalSslConfiguration(ssl)) + case (None, Some(ssl)) => Some(RorSsl.OnlyInternodeSslConfiguration(ssl)) + case (Some(externalSsl), Some(internalSsl)) => Some(RorSsl.ExternalAndInternodeSslConfiguration(externalSsl, internalSsl)) + case (None, None) => None + } + } } - private def sslInternodeConfigurationDecoder(basePath: Path): Decoder[Option[InternodeSslConfiguration]] = Decoder.instance { c => + private def sslInternodeConfigurationDecoder(basePath: Path, + fipsMode: FipsMode): Decoder[Option[InternodeSslConfiguration]] = Decoder.instance { c => whenEnabled(c) { for { certificateVerification <- c.downField(consts.certificateVerification).as[Option[Boolean]] @@ -266,12 +323,14 @@ private object SslDecoders extends Logging { allowedCiphers = sslCommonProperties.allowedCiphers, clientAuthenticationEnabled = sslCommonProperties.clientAuthentication.getOrElse(false), certificateVerificationEnabled = certificateVerification.orElse(verification).getOrElse(false), - hostnameVerificationEnabled = hostnameVerification.getOrElse(false) + hostnameVerificationEnabled = hostnameVerification.getOrElse(false), + fipsMode = fipsMode ) } } - private def sslExternalConfigurationDecoder(basePath: Path): Decoder[Option[ExternalSslConfiguration]] = Decoder.instance { c => + private def sslExternalConfigurationDecoder(basePath: Path, + fipsMode: FipsMode): Decoder[Option[ExternalSslConfiguration]] = Decoder.instance { c => whenEnabled(c) { for { verification <- c.downField(consts.verification).as[Option[Boolean]] @@ -282,7 +341,8 @@ private object SslDecoders extends Logging { clientCertificateConfiguration = sslCommonProperties.clientCertificateConfiguration, allowedProtocols = sslCommonProperties.allowedProtocols, allowedCiphers = sslCommonProperties.allowedCiphers, - clientAuthenticationEnabled = sslCommonProperties.clientAuthentication.orElse(verification).getOrElse(false) + clientAuthenticationEnabled = sslCommonProperties.clientAuthentication.orElse(verification).getOrElse(false), + fipsMode = fipsMode ) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala index ed1f15abbf..a11b51e26b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.configuration import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexSettings import tech.beshu.ror.configuration.index.{IndexConfigError, IndexTestConfigManager} import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.IndexParsingError import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index e8fdf4fda6..58ef29a240 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -17,7 +17,7 @@ package tech.beshu.ror.configuration.loader import monix.eval.Task -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.{LoadFromFileSettings, LoadFromIndexSettings} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} import tech.beshu.ror.configuration.RawRorConfig import tech.beshu.ror.configuration.RorConfigLoading.* import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala index 01e9b29076..ad39536c42 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala @@ -17,7 +17,7 @@ package tech.beshu.ror.configuration.loader import monix.eval.Task -import tech.beshu.ror.configuration.EsConfig.RorEsLevelSettings.LoadFromIndexSettings +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.TestRorConfig import tech.beshu.ror.configuration.TestRorConfigLoading.* diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 7440447df6..e57dd23a53 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -59,7 +59,7 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError.{KibanaRuleTogetherWith, KibanaUserDataRuleTogetherWith} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext -import tech.beshu.ror.configuration.EsConfig.LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled.SettingsType +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadEsConfigError import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* @@ -335,11 +335,6 @@ trait LogsShowInstances s"JWT variables are not allowed to be used in Groups rule" } - implicit val settingsTypeShow: Show[SettingsType] = Show.show { - case SettingsType.Ssl => "SSL configuration" - case SettingsType.Fips => "FIBS configuration" - } - def obfuscatedHeaderShow(obfuscatedHeaders: Iterable[Header.Name]): Show[Header] = { Show.show[Header] { case Header(name, _) if obfuscatedHeaders.exists(_ === name) => s"${name.show}=" @@ -402,4 +397,11 @@ trait LogsShowInstances case MustBePresent(value) => value.show case AccessRequirement.MustBeAbsent(value) => s"~${value.show}" } + + implicit val loadEsConfigErrorShow: Show[LoadEsConfigError] = Show.show { + case LoadEsConfigError.FileNotFound(file) => s"Cannot find elasticsearch settings file: [${file.show}]" + case LoadEsConfigError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" + case LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" + } + } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala similarity index 86% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala index df806921c2..bbade9837d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala @@ -20,12 +20,12 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} -import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorBootConfiguration} +import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorBootSettings} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} -class RorBootConfigurationTest +class RorBootSettingsTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = SystemContext.default @@ -33,7 +33,7 @@ class RorBootConfigurationTest "A ReadonlyREST ES starting settings" should { "be loaded from elasticsearch config file" when { "configuration contains not started response code" in { - val config = RorBootConfiguration + val config = RorBootSettings .load(esEnvFrom("/boot_tests/boot_config/not_started_code_defined/")) .runSyncUnsafe() @@ -42,7 +42,7 @@ class RorBootConfigurationTest )) } "configuration contains failed to start response code" in { - val config = RorBootConfiguration + val config = RorBootSettings .load(esEnvFrom("/boot_tests/boot_config/failed_to_start_code_defined/")) .runSyncUnsafe() @@ -51,22 +51,22 @@ class RorBootConfigurationTest )) } "configuration contains all codes" in { - val config = RorBootConfiguration + val config = RorBootSettings .load(esEnvFrom("/boot_tests/boot_config/all_codes_defined/")) .runSyncUnsafe() - config should be(Right(RorBootConfiguration( + config should be(Right(RorBootSettings( rorNotStartedResponse = RorNotStartedResponse(RorNotStartedResponse.HttpCode.`403`), rorFailedToStartResponse = RorFailedToStartResponse(RorFailedToStartResponse.HttpCode.`503`), ))) } } "there is no response codes defined in config, default values should be used" in { - val config = RorBootConfiguration + val config = RorBootSettings .load(esEnvFrom("/boot_tests/boot_config/")) .runSyncUnsafe() - config should be(Right(RorBootConfiguration( + config should be(Right(RorBootSettings( rorNotStartedResponse = RorNotStartedResponse(RorNotStartedResponse.HttpCode.`403`), rorFailedToStartResponse = RorFailedToStartResponse(RorFailedToStartResponse.HttpCode.`403`), ))) @@ -77,7 +77,7 @@ class RorBootConfigurationTest val configFolderPath = "/boot_tests/boot_config/not_started_code_malformed/" val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorBootConfiguration.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorBootSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( s"Cannot load ROR boot configuration from file $expectedFilePath. " + s"Cause: Unsupported response code [200] for readonlyrest.not_started_response_code. Supported response codes are: 403, 503." @@ -88,7 +88,7 @@ class RorBootConfigurationTest val configFolderPath = "/boot_tests/boot_config/failed_to_start_code_malformed/" val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorBootConfiguration.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorBootSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( s"Cannot load ROR boot configuration from file $expectedFilePath. " + s"Cause: Unsupported response code [200] for readonlyrest.failed_to_start_response_code. Supported response codes are: 403, 503." diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 935d3f8369..fcce1bc399 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,13 +28,14 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.configuration.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} @@ -58,14 +59,14 @@ class IndexLevelActionFilter(nodeName: String, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfig: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfig.boot) private val ror = ReadonlyRest.create( new EsIndexJsonContentService(client), @@ -207,7 +208,7 @@ class IndexLevelActionFilter(nodeName: String, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfig) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index ec8018e604..d3ce42e587 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -24,7 +25,6 @@ import org.elasticsearch.action.{ActionRequest, ActionResponse} import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject import org.elasticsearch.common.io.stream.NamedWriteableRegistry import org.elasticsearch.common.network.NetworkService import org.elasticsearch.common.settings.* @@ -36,8 +36,9 @@ import org.elasticsearch.http.{HttpPreRequest, HttpServerTransport} import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler +import org.elasticsearch.injection.guice.Inject import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.telemetry.tracing.Tracer @@ -47,16 +48,14 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.configuration.EsConfigBasedRorSettings +import tech.beshu.ror.configuration.RorSsl.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction @@ -65,8 +64,10 @@ import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, Transpo import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -101,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -128,7 +129,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(nodeClient), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -162,14 +163,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -180,14 +180,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -206,7 +205,6 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,7 +227,6 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RestRRAdminAction(), new RestRRAuthMockAction(), new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..95b82d2e22 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.configuration.RorBootSettings +import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => From 35ba44900b4c764f3c066266ecea8d060bdac6d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 8 Jul 2025 15:04:06 +0200 Subject: [PATCH 011/103] refactoring --- ...sedCoreFactory.scala => CoreFactory.scala} | 29 +++-- ...cala => JsonStaticVariablesResolver.scala} | 10 +- .../factory/RorDependencies.scala} | 17 ++- .../tech/beshu/ror/api/AuthMockApi.scala | 14 +-- .../scala/tech/beshu/ror/api/ConfigApi.scala | 24 ++-- .../tech/beshu/ror/api/TestConfigApi.scala | 24 ++-- .../tech/beshu/ror/boot/ReadonlyRest.scala | 85 ++++++++------- .../tech/beshu/ror/boot/RorInstance.scala | 50 +++++---- .../boot/engines/BaseReloadableEngine.scala | 34 +++--- .../beshu/ror/boot/engines/ConfigHash.scala | 6 +- .../MainConfigBasedReloadableEngine.scala | 28 +++-- .../TestConfigBasedReloadableEngine.scala | 53 +++++---- .../EsConfigBasedRorSettings.scala | 10 +- ...awRorConfig.scala => RawRorSettings.scala} | 6 +- ...r.scala => RawRorSettingsYamlParser.scala} | 26 ++--- .../ror/configuration/RorBootSettings.scala | 2 +- .../ror/configuration/RorConfigLoading.scala | 103 ------------------ .../ror/configuration/SslConfiguration.scala | 2 +- .../configuration/TestRorConfigLoading.scala | 73 ------------- ...tRorConfig.scala => TestRorSettings.scala} | 10 +- ...cala => YamlFileBasedSettingsLoader.scala} | 20 ++-- .../index/BaseIndexConfigManager.scala | 33 ------ .../ror/configuration/index/Config.scala | 1 + .../index/IndexConfigError.scala | 39 ------- ...entServiceBasedIndexSettingsManager.scala} | 30 ++--- ...erviceBasedIndexTestSettingsManager.scala} | 50 +++++---- .../index/IndexSettingsManager.scala | 59 ++++++++++ ...ader.scala => FileRorSettingsLoader.scala} | 22 ++-- .../loader/LoadRawRorConfig.scala | 101 +++++++++++++++-- .../loader/LoadRawTestRorConfig.scala | 71 ++++++++++-- ...igLoader.scala => RorSettingsLoader.scala} | 15 +-- .../ror/configuration/loader/domain.scala | 4 +- .../ror/configuration/loader/package.scala | 26 ----- .../BaseYamlLoadedAccessControlTest.scala | 4 +- .../unit/acl/factory/AuditSettingsTests.scala | 31 +++--- .../unit/acl/factory/CoreFactoryTests.scala | 4 +- .../factory/ImpersonationWarningsTests.scala | 6 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 8 +- .../unit/boot/ReadonlyRestStartingTests.scala | 44 ++++---- .../beshu/ror/unit/boot/RorIndexTest.scala | 8 +- ...est.scala => LoadRawRorSettingsTest.scala} | 16 +-- ... YamlFileBasedRorSettingsLoaderTest.scala} | 8 +- .../tech/beshu/ror/utils/TestsUtils.scala | 10 +- 43 files changed, 567 insertions(+), 649 deletions(-) rename core/src/main/scala/tech/beshu/ror/accesscontrol/factory/{RawRorConfigBasedCoreFactory.scala => CoreFactory.scala} (96%) rename core/src/main/scala/tech/beshu/ror/accesscontrol/factory/{JsonConfigStaticVariableResolver.scala => JsonStaticVariablesResolver.scala} (93%) rename core/src/main/scala/tech/beshu/ror/{configuration/RorConfig.scala => accesscontrol/factory/RorDependencies.scala} (74%) rename core/src/main/scala/tech/beshu/ror/configuration/{RawRorConfig.scala => RawRorSettings.scala} (84%) rename core/src/main/scala/tech/beshu/ror/configuration/{RawRorConfigYamlParser.scala => RawRorSettingsYamlParser.scala} (71%) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala rename core/src/main/scala/tech/beshu/ror/configuration/{TestRorConfig.scala => TestRorSettings.scala} (87%) rename core/src/main/scala/tech/beshu/ror/configuration/{YamlFileBasedConfigLoader.scala => YamlFileBasedSettingsLoader.scala} (74%) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigError.scala rename core/src/main/scala/tech/beshu/ror/configuration/index/{IndexConfigManager.scala => IndexJsonContentServiceBasedIndexSettingsManager.scala} (58%) rename core/src/main/scala/tech/beshu/ror/configuration/index/{IndexTestConfigManager.scala => IndexJsonContentServiceBasedIndexTestSettingsManager.scala} (83%) create mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala rename core/src/main/scala/tech/beshu/ror/configuration/loader/{FileRorConfigLoader.scala => FileRorSettingsLoader.scala} (67%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{RorConfigLoader.scala => RorSettingsLoader.scala} (69%) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala rename core/src/test/scala/tech/beshu/ror/unit/configuration/{LoadRawRorConfigTest.scala => LoadRawRorSettingsTest.scala} (96%) rename core/src/test/scala/tech/beshu/ror/unit/configuration/{YamlFileBasedRorConfigLoaderTest.scala => YamlFileBasedRorSettingsLoaderTest.scala} (91%) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala similarity index 96% rename from core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala rename to core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index f79ea9c631..ee63137243 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RawRorConfigBasedCoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -24,7 +24,7 @@ import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.* import tech.beshu.ror.accesscontrol.EnabledAccessControlList.AccessControlListStaticContext -import tech.beshu.ror.accesscontrol.audit.LoggingContext +import tech.beshu.ror.accesscontrol.audit.{AuditingTool, LoggingContext} import tech.beshu.ror.accesscontrol.blocks.Block.{RuleDefinition, Verbosity} import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning.ImpersonationWarningSupport import tech.beshu.ror.accesscontrol.blocks.definitions.UserDef.Mode @@ -42,6 +42,7 @@ import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.* import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.* import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RorDependencies.ImpersonationWarningsReader import tech.beshu.ror.accesscontrol.factory.decoders.definitions.* import tech.beshu.ror.accesscontrol.factory.decoders.ruleDecoders.ruleDecoderBy import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleDecoder @@ -49,8 +50,7 @@ import tech.beshu.ror.accesscontrol.factory.decoders.{AuditingSettingsDecoder, G import tech.beshu.ror.accesscontrol.utils.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.FieldListResult.{FieldListValue, NoField} -import tech.beshu.ror.configuration.RorConfig.ImpersonationWarningsReader -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.EsVersion import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* @@ -58,10 +58,11 @@ import tech.beshu.ror.utils.ScalaOps.* import tech.beshu.ror.utils.yaml.YamlOps final case class Core(accessControl: AccessControlList, - rorConfig: RorConfig) + dependencies: RorDependencies, + auditingSettings: Option[AuditingTool.Settings]) trait CoreFactory { - def createCoreFrom(config: RawRorConfig, + def createCoreFrom(config: RawRorSettings, rorIndexNameConfiguration: RorConfigurationIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, @@ -72,14 +73,14 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) (implicit systemContext: SystemContext) extends CoreFactory with Logging { - override def createCoreFrom(config: RawRorConfig, + override def createCoreFrom(config: RawRorSettings, rorIndexNameConfiguration: RorConfigurationIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] = { - config.configJson \\ Attributes.rorSectionName match { + config.settingsJson \\ Attributes.rorSectionName match { case Nil => createCoreFromRorSection( - config.configJson, + config.settingsJson, rorIndexNameConfiguration, httpClientFactory, ldapConnectionPoolProvider, @@ -101,7 +102,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { - val jsonConfigResolver = new JsonConfigStaticVariableResolver( + val jsonConfigResolver = new JsonStaticVariablesResolver( systemContext.envVarsProvider, TransformationCompiler.withoutAliases(systemContext.variablesFunctions), ) @@ -127,8 +128,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) enabled <- AsyncDecoderCreator.from(coreEnabilityDecoder) core <- if (!enabled) { - AsyncDecoderCreator - .from(Decoder.const(Core(DisabledAccessControlList, RorConfig.disabled))) + AsyncDecoderCreator.from(Decoder.const(Core(DisabledAccessControlList, RorDependencies.noOp, None))) } else { for { globalSettings <- AsyncDecoderCreator.from(GlobalStaticSettingsDecoder.instance(rorConfigurationIndex)) @@ -386,15 +386,14 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) (fromBlocks :+ fromUserDefs :+ fromImpersonatorDefs).combineAll } - val rorConfig = RorConfig( - services = RorConfig.Services( + val rorDependencies = RorDependencies( + services = RorDependencies.Services( authenticationServices = authenticationServices.items.map(_.id), authorizationServices = authorizationServices.items.map(_.id), ldaps = ldapServices.items.map(_.id) ), localUsers = localUsers, impersonationWarningsReader = new ImpersonationWarningsCombinedReader(blocksNel.map(_.impersonationWarnings).toList: _*), - auditingSettings = auditingTools, ) val accessControl = new EnabledAccessControlList( blocks, @@ -404,7 +403,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) obfuscatedHeaders ) ): AccessControlList - Core(accessControl, rorConfig) + Core(accessControl, rorDependencies, auditingTools) } decoder.apply(c) } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonConfigStaticVariableResolver.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonStaticVariablesResolver.scala similarity index 93% rename from core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonConfigStaticVariableResolver.scala rename to core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonStaticVariablesResolver.scala index 0d31655771..18bc99a71b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonConfigStaticVariableResolver.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/JsonStaticVariablesResolver.scala @@ -21,12 +21,12 @@ import eu.timepit.refined.types.string.NonEmptyString import io.circe.Json import tech.beshu.ror.accesscontrol.blocks.variables.startup.StartupResolvableVariableCreator import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler -import tech.beshu.ror.accesscontrol.factory.JsonConfigStaticVariableResolver.* +import tech.beshu.ror.accesscontrol.factory.JsonStaticVariablesResolver.* import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.EnvVarsProvider -class JsonConfigStaticVariableResolver(envProvider: EnvVarsProvider, - transformationCompiler: TransformationCompiler) { +class JsonStaticVariablesResolver(envProvider: EnvVarsProvider, + transformationCompiler: TransformationCompiler) { private val variableCreator = new StartupResolvableVariableCreator(transformationCompiler) @@ -66,7 +66,6 @@ class JsonConfigStaticVariableResolver(envProvider: EnvVarsProvider, } } - private def resolvedStringToJson(resolvedStr: String, original: Json) = { def isJsonPrimitive(json: Json) = !(json.isObject || json.isArray) @@ -81,7 +80,6 @@ class JsonConfigStaticVariableResolver(envProvider: EnvVarsProvider, } } - private def tryToResolveAllStaticSingleVars(str: NonEmptyString, errors: ResolvingErrors): String = { variableCreator.createSingleVariableFrom(str) match { case Right(variable) => @@ -113,7 +111,7 @@ class JsonConfigStaticVariableResolver(envProvider: EnvVarsProvider, } } -object JsonConfigStaticVariableResolver { +object JsonStaticVariablesResolver { final case class ResolvingError(msg: String) extends AnyVal private final case class ResolvingErrors(var values: Vector[ResolvingError]) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RorDependencies.scala similarity index 74% rename from core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala rename to core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RorDependencies.scala index 244193c748..1abc139281 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/RorDependencies.scala @@ -14,25 +14,22 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.accesscontrol.factory -import tech.beshu.ror.accesscontrol.audit.AuditingTool import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} import tech.beshu.ror.accesscontrol.domain.{LocalUsers, RequestId} -import tech.beshu.ror.configuration.RorConfig.ImpersonationWarningsReader +import tech.beshu.ror.accesscontrol.factory.RorDependencies.ImpersonationWarningsReader import scala.annotation.unused -// todo: rename -final case class RorConfig(services: RorConfig.Services, - localUsers: LocalUsers, - impersonationWarningsReader: ImpersonationWarningsReader, - auditingSettings: Option[AuditingTool.Settings]) +final case class RorDependencies(services: RorDependencies.Services, + localUsers: LocalUsers, + impersonationWarningsReader: ImpersonationWarningsReader) -object RorConfig { - def disabled: RorConfig = RorConfig(RorConfig.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader, None) +object RorDependencies { + def noOp: RorDependencies = RorDependencies(RorDependencies.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader) final case class Services(authenticationServices: Seq[ExternalAuthenticationService#Id], authorizationServices: Seq[ExternalAuthorizationService#Id], diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index fd8aed1fa2..5af9e763e8 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -30,9 +30,9 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenti import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RequestId, User} +import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.boot.RorInstance.{IndexConfigUpdateError, TestConfig} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.RorConfig import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.CirceErrorOps @@ -65,7 +65,7 @@ class AuthMockApi(rorInstance: RorInstance) .map(_.merge) } - private def readCurrentAuthMocks(services: RorConfig.Services) + private def readCurrentAuthMocks(services: RorDependencies.Services) (implicit requestId: RequestId): AuthMockResponse.ProvideAuthMock.CurrentAuthMocks = { val ldaps = services.ldaps.map { serviceId => toAuthMockService(serviceId, rorInstance.mocksProvider.ldapServiceWith(serviceId)) @@ -99,7 +99,7 @@ class AuthMockApi(rorInstance: RorInstance) } private def readCurrentAuthServices() - (implicit requestId: RequestId): EitherT[Task, AuthMockResponse, RorConfig.Services] = { + (implicit requestId: RequestId): EitherT[Task, AuthMockResponse, RorDependencies.Services] = { EitherT(withRorConfigAuthServices( action = identity, onNotSet = AuthMockResponse.UpdateAuthMock.NotConfigured.apply, @@ -107,15 +107,15 @@ class AuthMockApi(rorInstance: RorInstance) )) } - private def withRorConfigAuthServices[A, B](action: RorConfig.Services => B, + private def withRorConfigAuthServices[A, B](action: RorDependencies.Services => B, onNotSet: String => A, onInvalidated: String => A) (implicit requestId: RequestId): Task[Either[A, B]] = { rorInstance.currentTestConfig().map { case TestConfig.NotSet => Left(onNotSet(testSettingsNotConfiguredMessage)) - case TestConfig.Present(config, _, _, _) => - Right(action(config.services)) + case TestConfig.Present(_, dependencies, _, _) => + Right(action(dependencies.services)) case _:TestConfig.Invalidated => Left(onInvalidated(testSettingsInvalidatedMessage)) } @@ -126,7 +126,7 @@ class AuthMockApi(rorInstance: RorInstance) private val testSettingsNotConfiguredMessage = "ROR Test settings are not configured. To use Auth Services Mock ROR has to have Test settings active." private def validateAuthMocks(updateRequest: UpdateMocksRequest, - services: RorConfig.Services): EitherT[Task, AuthMockResponse, Unit] = { + services: RorDependencies.Services): EitherT[Task, AuthMockResponse, Unit] = { updateRequest .services .map { diff --git a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala index b0f59098a3..fda45983eb 100644 --- a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala @@ -29,17 +29,17 @@ import tech.beshu.ror.api.ConfigApi.ConfigResponse.* import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigReloadError, RawConfigReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} -import tech.beshu.ror.configuration.index.IndexConfigError.IndexConfigNotExist -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.SpecializedError -import tech.beshu.ror.configuration.loader.FileRorConfigLoader +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +import tech.beshu.ror.configuration.loader.FileRorSettingsLoader +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class ConfigApi(rorInstance: RorInstance, - rawRorConfigYamlParser: RawRorConfigYamlParser, - indexConfigManager: IndexConfigManager, - fileConfigLoader: FileRorConfigLoader, + rawRorConfigYamlParser: RawRorSettingsYamlParser, + indexConfigManager: IndexSettingsManager[RawRorSettings], + fileConfigLoader: FileRorSettingsLoader, rorConfigurationIndex: RorConfigurationIndex) extends Logging { @@ -102,8 +102,8 @@ class ConfigApi(rorInstance: RorInstance, .map { case Right(config) => ProvideIndexConfig.Config(config.raw) - case Left(SpecializedError(error: IndexConfigNotExist.type)) => - ProvideIndexConfig.ConfigNotFound(Show[IndexConfigError].show(error)) + case Left(SpecializedError(error: LoadingIndexSettingsError.IndexNotExist.type)) => + ProvideIndexConfig.ConfigNotFound(Show[LoadingIndexSettingsError].show(error)) case Left(error) => ProvideIndexConfig.Failure(error.show) } @@ -114,13 +114,13 @@ class ConfigApi(rorInstance: RorInstance, .left.map(error => ConfigResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage.show}]")) } - private def rorConfigFrom(configString: String): EitherT[Task, ConfigResponse, RawRorConfig] = EitherT { + private def rorConfigFrom(configString: String): EitherT[Task, ConfigResponse, RawRorSettings] = EitherT { rawRorConfigYamlParser .fromString(configString) .map(_.left.map(error => UpdateIndexConfig.Failure(error.show))) } - private def forceReloadAndSaveNewConfig(config: RawRorConfig) + private def forceReloadAndSaveNewConfig(config: RawRorSettings) (implicit requestId: RequestId): EitherT[Task, ConfigResponse, Unit] = { EitherT(rorInstance.forceReloadAndSave(config)) .leftMap { diff --git a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala index cb8cc4ac6b..329990e4e9 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.api.TestConfigApi.{TestConfigRequest, TestConfigResponse} import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, RawConfigReloadError, TestConfig} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* @@ -38,7 +38,7 @@ import scala.concurrent.duration.* import scala.util.Try class TestConfigApi(rorInstance: RorInstance, - rawRorConfigYamlParser: RawRorConfigYamlParser) { + rawRorConfigYamlParser: RawRorSettingsYamlParser) { import tech.beshu.ror.api.TestConfigApi.Utils.* import tech.beshu.ror.api.TestConfigApi.Utils.decoders.* @@ -71,7 +71,7 @@ class TestConfigApi(rorInstance: RorInstance, .left.map(error => TestConfigResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage}]")) } - private def rorTestConfig(configString: String): EitherT[Task, TestConfigResponse, RawRorConfig] = EitherT { + private def rorTestConfig(configString: String): EitherT[Task, TestConfigResponse, RawRorSettings] = EitherT { rawRorConfigYamlParser .fromString(configString) .map(_.left.map(error => TestConfigResponse.UpdateTestConfig.FailedResponse(error.show))) @@ -96,12 +96,12 @@ class TestConfigApi(rorInstance: RorInstance, .map { case TestConfig.NotSet => TestConfigResponse.ProvideTestConfig.TestSettingsNotConfigured("ROR Test settings are not configured") - case TestConfig.Present(config, rawConfig, configuredTtl, validTo) => + case TestConfig.Present(rawConfig, dependencies, configuredTtl, validTo) => TestConfigResponse.ProvideTestConfig.CurrentTestSettings( ttl = apiFormat(configuredTtl), validTo = validTo, settings = rawConfig, - warnings = config.impersonationWarningsReader.read().map(toWarningDto) + warnings = dependencies.impersonationWarningsReader.read().map(toWarningDto) ) case TestConfig.Invalidated(recentConfig, ttl) => TestConfigResponse.ProvideTestConfig.TestSettingsInvalidated("ROR Test settings are invalidated", recentConfig, apiFormat(ttl)) @@ -115,18 +115,18 @@ class TestConfigApi(rorInstance: RorInstance, .map { case TestConfig.NotSet => TestConfigResponse.ProvideLocalUsers.TestSettingsNotConfigured("ROR Test settings are not configured") - case TestConfig.Present(config, _, _, _) => - val filteredLocalUsers = config.localUsers.users -- loggedUser.map(_.id) + case TestConfig.Present(_, dependencies, _, _) => + val filteredLocalUsers = dependencies.localUsers.users -- loggedUser.map(_.id) TestConfigResponse.ProvideLocalUsers.SuccessResponse( users = filteredLocalUsers.map(_.value.value).toList, - unknownUsers = config.localUsers.unknownUsers + unknownUsers = dependencies.localUsers.unknownUsers ) case _:TestConfig.Invalidated => TestConfigResponse.ProvideLocalUsers.TestSettingsInvalidated("ROR Test settings are invalidated") } } - private def forceReloadTestConfig(config: RawRorConfig, + private def forceReloadTestConfig(config: RawRorSettings, ttl: PositiveFiniteDuration) (implicit requestId: RequestId): EitherT[Task, TestConfigResponse, TestConfigResponse] = { EitherT( @@ -138,7 +138,7 @@ class TestConfigApi(rorInstance: RorInstance, TestConfigResponse.UpdateTestConfig.SuccessResponse( message = "updated settings", validTo = newTestConfig.validTo, - warnings = newTestConfig.config.impersonationWarningsReader.read().map(toWarningDto) + warnings = newTestConfig.dependencies.impersonationWarningsReader.read().map(toWarningDto) ) } .leftMap { @@ -192,12 +192,12 @@ object TestConfigApi { object ProvideTestConfig { final case class CurrentTestSettings(ttl: FiniteDuration, validTo: Instant, - settings: RawRorConfig, + settings: RawRorSettings, warnings: List[Warning]) extends ProvideTestConfig final case class TestSettingsNotConfigured(message: String) extends ProvideTestConfig final case class TestSettingsInvalidated(message: String, - settings: RawRorConfig, + settings: RawRorSettings, ttl: FiniteDuration) extends ProvideTestConfig } diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index bebc47f083..6d08556b3e 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -35,7 +35,7 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.index.{IndexConfigManager, IndexTestConfigManager} +import tech.beshu.ror.configuration.index.* import tech.beshu.ror.configuration.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* @@ -54,9 +54,9 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - rorYamlParser <- lift(new RawRorConfigYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) - indexConfigManager <- lift(new IndexConfigManager(indexContentService, rorYamlParser)) - indexTestConfigManager <- lift(new IndexTestConfigManager(indexContentService, rorYamlParser)) + rorYamlParser <- lift(new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) + indexConfigManager <- lift(new IndexJsonContentServiceBasedIndexSettingsManager(indexContentService, rorYamlParser)) + indexTestConfigManager <- lift(new IndexJsonContentServiceBasedIndexTestSettingsManager(indexContentService, rorYamlParser)) loadedRorConfig <- loadRorConfig(esConfig, indexConfigManager) loadedTestRorConfig <- loadRorTestConfig(esConfig, indexTestConfigManager) instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig, indexConfigManager, indexTestConfigManager) @@ -68,7 +68,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadRorConfig(esConfig: EsConfigBasedRorSettings, - indexConfigManager: IndexConfigManager): EitherT[Task, StartingFailure, LoadedRorConfig[RawRorConfig]] = { + indexConfigManager: IndexSettingsManager[RawRorSettings]): EitherT[Task, StartingFailure, RawRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => EitherT(LoadRawRorConfig.loadFromFile(settings)) @@ -84,10 +84,10 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadRorTestConfig(esConfig: EsConfigBasedRorSettings, - indexTestConfigManager: IndexTestConfigManager): EitherT[Task, StartingFailure, LoadedTestRorConfig[TestRorConfig]] = { + indexTestConfigManager: IndexSettingsManager[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(TestRorConfig.NotSet)) + EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => // todo: move // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) @@ -103,13 +103,13 @@ class ReadonlyRest(coreFactory: CoreFactory, }.leftFlatMap { case LoadedTestRorConfig.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) case LoadedTestRorConfig.IndexUnknownStructure => logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) case LoadedTestRorConfig.IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](LoadedTestRorConfig(notSetTestRorConfig)) + EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) } } } @@ -130,79 +130,79 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def startRor(esConfig: EsConfigBasedRorSettings, - loadedConfig: LoadedRorConfig[RawRorConfig], - loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig], - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager) = { + loadedConfig: RawRorSettings, + loadedTestRorConfig: TestRorSettings, + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings]) = { for { - mainEngine <- EitherT(loadRorCore(loadedConfig.value, esConfig.rorConfigIndex)) + mainEngine <- EitherT(loadRorEngine(loadedConfig, esConfig.rorConfigIndex)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedConfig) } yield rorInstance } - private def loadTestEngine(esConfig: EsConfigBasedRorSettings, loadedTestRorConfig: LoadedTestRorConfig[TestRorConfig]) = { - loadedTestRorConfig.value match { - case TestRorConfig.NotSet => + private def loadTestEngine(esConfig: EsConfigBasedRorSettings, loadedTestRorConfig: TestRorSettings) = { + loadedTestRorConfig match { + case TestRorSettings.NotSet => Task.now(TestEngine.NotConfigured) - case config: TestRorConfig.Present if !config.isExpired(systemContext.clock) => + case config: TestRorSettings.Present if !config.isExpired(systemContext.clock) => loadActiveTestEngine(esConfig, config) - case config: TestRorConfig.Present => + case config: TestRorSettings.Present => loadInvalidatedTestEngine(config) } } - private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testConfig: TestRorConfig.Present) = { + private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testConfig: TestRorSettings.Present) = { for { _ <- Task.delay(authServicesMocksProvider.update(testConfig.mocks)) - testEngine <- loadRorCore(testConfig.rawConfig, esConfig.rorConfigIndex) + testEngine <- loadRorEngine(testConfig.rawSettings, esConfig.rorConfigIndex) .map { case Right(loadedEngine) => TestEngine.Configured( engine = loadedEngine, - config = testConfig.rawConfig, + config = testConfig.rawSettings, expiration = expirationConfig(testConfig.expiration) ) case Left(startingFailure) => logger.error(s"Unable to start test engine. Cause: ${startingFailure.message.show}. Test settings engine will be marked as invalidated.") - TestEngine.Invalidated(testConfig.rawConfig, expirationConfig(testConfig.expiration)) + TestEngine.Invalidated(testConfig.rawSettings, expirationConfig(testConfig.expiration)) } } yield testEngine } - private def loadInvalidatedTestEngine(testConfig: TestRorConfig.Present) = { + private def loadInvalidatedTestEngine(testConfig: TestRorSettings.Present) = { Task .delay(authServicesMocksProvider.update(testConfig.mocks)) .map { _ => - TestEngine.Invalidated(testConfig.rawConfig, expirationConfig(testConfig.expiration)) + TestEngine.Invalidated(testConfig.rawSettings, expirationConfig(testConfig.expiration)) } } - private def expirationConfig(config: TestRorConfig.Present.ExpirationConfig): TestEngine.Expiration = { + private def expirationConfig(config: TestRorSettings.Present.ExpirationConfig): TestEngine.Expiration = { TestEngine.Expiration(config.ttl, config.validTo) } private def createRorInstance(esConfig: EsConfigBasedRorSettings, engine: Engine, testEngine: TestEngine, - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager, - loadedConfig: LoadedRorConfig[RawRorConfig]) = { + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings], + loadedConfig: RawRorSettings) = { EitherT.right[StartingFailure] { val rorSettingsFile = esConfig.loadingRorCoreStrategy.rorSettingsFile val rorSettingsMaxSize = esConfig.loadingRorCoreStrategy.rorSettingsMaxSize val rorConfigIndex = esConfig.rorConfigIndex esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig.value), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) } } } - private[ror] def loadRorCore(config: RawRorConfig, - rorIndexNameConfiguration: RorConfigurationIndex): Task[Either[StartingFailure, Engine]] = { + private[ror] def loadRorEngine(config: RawRorSettings, + rorIndexNameConfiguration: RorConfigurationIndex): Task[Either[StartingFailure, Engine]] = { val httpClientsFactory = new AsyncHttpClientsFactory val ldapConnectionPoolProvider = new UnboundidLdapConnectionPoolProvider @@ -222,14 +222,15 @@ class ReadonlyRest(coreFactory: CoreFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, core: Core): EitherT[Task, NonEmptyList[CoreCreationError], Engine] = { implicit val loggingContext: LoggingContext = LoggingContext(core.accessControl.staticContext.obfuscatedHeaders) - EitherT(createAuditingTool(core)) + EitherT(createAuditingTool(core.auditingSettings)) .map { auditingTool => val decoratedCore = Core( accessControl = new AccessControlListLoggingDecorator( underlying = core.accessControl, auditingTool = auditingTool ), - rorConfig = core.rorConfig + dependencies = core.dependencies, + auditingSettings = core.auditingSettings ) new Engine( core = decoratedCore, @@ -240,9 +241,9 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def createAuditingTool(core: Core) + private def createAuditingTool(auditingSettings: Option[AuditingTool.Settings]) (implicit loggingContext: LoggingContext): Task[Either[NonEmptyList[CoreCreationError], Option[AuditingTool]]] = { - core.rorConfig.auditingSettings + auditingSettings .map(settings => AuditingTool.create(settings, auditSinkServiceCreator)(using systemContext.clock, loggingContext)) .sequence .map { @@ -275,7 +276,7 @@ class ReadonlyRest(coreFactory: CoreFactory, StartingFailure(errorsMessage) } - private def notSetTestRorConfig: TestRorConfig = TestRorConfig.NotSet + private def notSetTestRorConfig: TestRorSettings = TestRorSettings.NotSet } object ReadonlyRest { @@ -283,7 +284,7 @@ object ReadonlyRest { final case class StartingFailure(message: String, throwable: Option[Throwable] = None) final case class MainEngine(engine: Engine, - config: RawRorConfig) + config: RawRorSettings) sealed trait TestEngine @@ -291,10 +292,10 @@ object ReadonlyRest { object NotConfigured extends TestEngine final case class Configured(engine: Engine, - config: RawRorConfig, + config: RawRorSettings, expiration: Expiration) extends TestEngine - final case class Invalidated(config: RawRorConfig, + final case class Invalidated(config: RawRorSettings, expiration: Expiration) extends TestEngine final case class Expiration(ttl: PositiveFiniteDuration, validTo: Instant) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 62332ab642..9fec1e0630 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -29,13 +29,15 @@ import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} import tech.beshu.ror.boot.engines.{Engines, MainConfigBasedReloadableEngine, TestConfigBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager, IndexTestConfigManager, SavingIndexConfigError} -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error -import tech.beshu.ror.configuration.loader.FileRorConfigLoader -import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser, RorConfig} +import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +import tech.beshu.ror.configuration.loader.FileRorSettingsLoader +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -47,8 +49,8 @@ class RorInstance private(boot: ReadonlyRest, mainReloadInProgress: Semaphore[Task], initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager, + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorSettingsIndex: RorConfigurationIndex, rorSettingsFile: File, rorSettingsMaxSize: Information) @@ -83,13 +85,13 @@ class RorInstance private(boot: ReadonlyRest, rorSettingsIndex ) - private val rarRorConfigYamlParser = new RawRorConfigYamlParser(rorSettingsMaxSize) + private val rarRorConfigYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) private val configRestApi = new ConfigApi( rorInstance = this, rarRorConfigYamlParser, indexConfigManager, - new FileRorConfigLoader(rorSettingsFile, rarRorConfigYamlParser), + new FileRorSettingsLoader(rorSettingsFile, rarRorConfigYamlParser), rorSettingsIndex ) @@ -111,7 +113,7 @@ class RorInstance private(boot: ReadonlyRest, (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, Unit]] = aMainConfigEngine.forceReloadFromIndex() - def forceReloadAndSave(config: RawRorConfig) + def forceReloadAndSave(config: RawRorSettings) (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, Unit]] = aMainConfigEngine.forceReloadAndSave(config) @@ -120,7 +122,7 @@ class RorInstance private(boot: ReadonlyRest, anTestConfigEngine.currentTestConfig() } - def forceReloadTestConfigEngine(config: RawRorConfig, + def forceReloadTestConfigEngine(config: RawRorSettings, ttl: PositiveFiniteDuration) (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, TestConfig.Present]] = { anTestConfigEngine.forceReloadTestConfigEngine(config, ttl) @@ -226,32 +228,32 @@ object RorInstance { sealed trait RawConfigReloadError object RawConfigReloadError { final case class ReloadingFailed(failure: ReadonlyRest.StartingFailure) extends RawConfigReloadError - final case class ConfigUpToDate(config: RawRorConfig) extends RawConfigReloadError + final case class ConfigUpToDate(config: RawRorSettings) extends RawConfigReloadError object RorInstanceStopped extends RawConfigReloadError } sealed trait IndexConfigReloadWithUpdateError object IndexConfigReloadWithUpdateError { final case class ReloadError(undefined: RawConfigReloadError) extends IndexConfigReloadWithUpdateError - final case class IndexConfigSavingError(underlying: SavingIndexConfigError) extends IndexConfigReloadWithUpdateError + final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigReloadWithUpdateError } sealed trait IndexConfigReloadError object IndexConfigReloadError { - final case class LoadingConfigError(underlying: Error[IndexConfigError]) extends IndexConfigReloadError + final case class LoadingConfigError(underlying: Error[LoadingIndexSettingsError]) extends IndexConfigReloadError final case class ReloadError(underlying: RawConfigReloadError) extends IndexConfigReloadError } sealed trait IndexConfigUpdateError object IndexConfigUpdateError { - final case class IndexConfigSavingError(underlying: SavingIndexConfigError) extends IndexConfigUpdateError + final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigUpdateError case object TestSettingsNotSet extends IndexConfigUpdateError case object TestSettingsInvalidated extends IndexConfigUpdateError } sealed trait IndexConfigInvalidationError object IndexConfigInvalidationError { - final case class IndexConfigSavingError(underlying: SavingIndexConfigError) extends IndexConfigInvalidationError + final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigInvalidationError } private sealed trait ScheduledReloadError @@ -263,19 +265,19 @@ object RorInstance { sealed trait TestConfig object TestConfig { case object NotSet extends TestConfig - final case class Present(config: RorConfig, - rawConfig: RawRorConfig, + final case class Present(rawConfig: RawRorSettings, + dependencies: RorDependencies, configuredTtl: PositiveFiniteDuration, validTo: Instant) extends TestConfig - final case class Invalidated(recent: RawRorConfig, + final case class Invalidated(recent: RawRorSettings, configuredTtl: PositiveFiniteDuration) extends TestConfig } def createWithPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager, + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings], refreshInterval: RefreshInterval, rorSettingsFile: File, rorSettingsMaxSize: Information, @@ -288,8 +290,8 @@ object RorInstance { def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager, + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorSettingsFile: File, rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) @@ -302,8 +304,8 @@ object RorInstance { mode: RorInstance.Mode, engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexConfigManager, - indexTestConfigManager: IndexTestConfigManager, + indexConfigManager: IndexSettingsManager[RawRorSettings], + indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorSettingsFile: File, rorSettingsMaxSize: Information, rorSettingsIndex: RorConfigurationIndex) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index 9dd65e48fe..d4d84d945d 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.boot.RorInstance.RawConfigReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.* @@ -127,18 +127,18 @@ private[engines] abstract class BaseReloadableEngine(val name: String, protected final def currentEngineState: EngineState = currentEngine.get() - protected def reloadEngine(newConfig: RawRorConfig) + protected def reloadEngine(newConfig: RawRorSettings) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { reloadEngineWithoutTtl(newConfig) } - protected def reloadEngine(newConfig: RawRorConfig, + protected def reloadEngine(newConfig: RawRorSettings, newConfigEngineTtl: PositiveFiniteDuration) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, ReloadResult] = { reloadEngineWithConfiguredTtl(newConfig, UpdatedConfigExpiration.ByTtl(newConfigEngineTtl)) } - protected def reloadEngine(newConfig: RawRorConfig, + protected def reloadEngine(newConfig: RawRorSettings, newConfigExpirationTime: Instant, configuredTtl: PositiveFiniteDuration) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { @@ -165,7 +165,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def reloadEngineWithConfiguredTtl(newConfig: RawRorConfig, + private def reloadEngineWithConfiguredTtl(newConfig: RawRorSettings, expiration: UpdatedConfigExpiration) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, ReloadResult] = { for { @@ -183,7 +183,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } yield expirationConfig } - private def reloadEngineWithoutTtl(newConfig: RawRorConfig) + private def reloadEngineWithoutTtl(newConfig: RawRorSettings) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { for { _ <- canBeReloaded(newConfig) @@ -191,7 +191,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } yield () } - private def runReload(newConfig: RawRorConfig, + private def runReload(newConfig: RawRorSettings, configExpiration: Option[UpdatedConfigExpiration]) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, EngineWithConfig] = { for { @@ -200,7 +200,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } yield newEngineWithConfig } - private def checkUpdateType(newConfig: RawRorConfig, + private def checkUpdateType(newConfig: RawRorSettings, newConfigExpiration: UpdatedConfigExpiration): EitherT[Task, RawConfigReloadError, EngineUpdateType] = { EitherT { Task.delay { @@ -234,7 +234,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def canBeReloaded(newConfig: RawRorConfig): EitherT[Task, RawConfigReloadError, Unit] = { + private def canBeReloaded(newConfig: RawRorSettings): EitherT[Task, RawConfigReloadError, Unit] = { EitherT { Task.delay { currentEngine.get() match { @@ -251,7 +251,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def reloadWith(newConfig: RawRorConfig, + private def reloadWith(newConfig: RawRorSettings, configExpiration: Option[UpdatedConfigExpiration]): EitherT[Task, RawConfigReloadError, EngineWithConfig] = EitherT { tryToLoadRorCore(newConfig) .map(_ @@ -275,8 +275,8 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def tryToLoadRorCore(config: RawRorConfig) = - boot.loadRorCore(config, rorConfigurationIndex) + private def tryToLoadRorCore(config: RawRorSettings) = + boot.loadRorEngine(config, rorConfigurationIndex) private def replaceCurrentEngine(newEngineWithConfig: EngineWithConfig) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { @@ -426,29 +426,29 @@ object BaseReloadableEngine { private[engines] object InitialEngine { case object NotConfigured extends InitialEngine final case class Configured(engine: Engine, - config: RawRorConfig, + config: RawRorSettings, expirationConfig: Option[EngineExpirationConfig]) extends InitialEngine - final case class Invalidated(config: RawRorConfig, + final case class Invalidated(config: RawRorSettings, expirationConfig: EngineExpirationConfig) extends InitialEngine } private[engines] final case class ReloadResult(engine: Engine, expirationConfig: EngineExpirationConfig) - private[engines] final case class InvalidationResult(config: RawRorConfig, + private[engines] final case class InvalidationResult(config: RawRorSettings, expirationConfig: EngineExpirationConfig) private[engines] final case class EngineExpirationConfig(ttl: PositiveFiniteDuration, validTo: Instant) private[engines] final case class EngineWithConfig(engine: Engine, - config: RawRorConfig, + config: RawRorSettings, expirationConfig: Option[EngineExpirationConfig]) private[engines] sealed trait EngineState private[engines] object EngineState { - final case class NotStartedYet(recentConfig: Option[RawRorConfig], + final case class NotStartedYet(recentConfig: Option[RawRorSettings], recentExpirationConfig: Option[EngineExpirationConfig]) extends EngineState diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala index b198ee2a40..9d5cddbcef 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala @@ -16,16 +16,16 @@ */ package tech.beshu.ror.boot.engines -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.utils.Hasher import scala.language.implicitConversions -private[engines] class ConfigHash(val config: RawRorConfig) extends AnyVal { +private[engines] class ConfigHash(val config: RawRorSettings) extends AnyVal { def hashString(): String = Hasher.Sha1.hashString(config.raw) } private[engines] object ConfigHash { - implicit def toConfigHash(config: RawRorConfig): ConfigHash = new ConfigHash(config) + implicit def toConfigHash(config: RawRorSettings): ConfigHash = new ConfigHash(config) } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala index d7519d4f62..63b6d7f89d 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala @@ -16,31 +16,29 @@ */ package tech.beshu.ror.boot.engines -import tech.beshu.ror.implicits.* import cats.data.EitherT -import cats.implicits.* import monix.catnap.Semaphore import monix.eval.Task import monix.execution.Scheduler import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.* +import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.RawConfigReloadError.{ConfigUpToDate, ReloadingFailed, RorInstanceStopped} -import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.index.IndexConfigManager -import tech.beshu.ror.configuration.index.SavingIndexConfigError.CannotSaveConfig +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, - initialEngine: (Engine, RawRorConfig), + initialEngine: (Engine, RawRorSettings), reloadInProgress: Semaphore[Task], - indexConfigManager: IndexConfigManager, + indexConfigManager: IndexSettingsManager[RawRorSettings], rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) @@ -52,7 +50,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, rorConfigurationIndex = rorConfigurationIndex ) { - def forceReloadAndSave(config: RawRorConfig) + def forceReloadAndSave(config: RawRorSettings) (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, Unit]] = { for { _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${config.hashString()}) ...")) @@ -75,7 +73,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexConfigSavingError(CannotSaveConfig)) => + case Left(IndexConfigSavingError(SavingIndexSettingsError.CannotSaveSettings)) => // todo: invalidate created core? logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") }) @@ -105,14 +103,14 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, } def reloadEngineUsingIndexConfig() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorConfig]] = { + (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorSettings]] = { reloadInProgress.withPermit { reloadEngineUsingIndexConfigWithoutPermit() } } private[boot] def reloadEngineUsingIndexConfigWithoutPermit() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorConfig]] = { + (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorSettings]] = { val result = for { newConfig <- EitherT(loadRorConfigFromIndex()) _ <- reloadEngine(newConfig) @@ -122,7 +120,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, result.value } - private def saveConfig(newConfig: RawRorConfig): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { + private def saveConfig(newConfig: RawRorSettings): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { for { saveResult <- indexConfigManager.save(newConfig, rorConfigurationIndex) } yield saveResult.left.map(IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala index 92128dc6dc..12da1f4cd6 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala @@ -16,32 +16,31 @@ */ package tech.beshu.ror.boot.engines -import tech.beshu.ror.implicits.* import cats.data.EitherT import monix.catnap.Semaphore import monix.eval.Task import monix.execution.Scheduler import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.implicits.* import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.{StartingFailure, TestEngine} -import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.* +import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpirationConfig, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.TestRorConfig.Present.ExpirationConfig -import tech.beshu.ror.configuration.index.{IndexTestConfigManager, SavingIndexConfigError} -import tech.beshu.ror.configuration.{RawRorConfig, TestRorConfig} +import tech.beshu.ror.configuration.TestRorSettings.Present.ExpirationConfig +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError +import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexTestConfigManager, + indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler) @@ -60,12 +59,12 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, TestConfig.Invalidated(recentConfig, expiration.ttl) case EngineState.Working(engineWithConfig, _) => val expiration = engineWithConfig.expirationConfig.getOrElse(throw new IllegalStateException("Test Config based engine should have an expiration config defined")) - TestConfig.Present(engineWithConfig.engine.core.rorConfig, engineWithConfig.config, expiration.ttl, expiration.validTo) + TestConfig.Present(engineWithConfig.config, engineWithConfig.engine.core.dependencies, expiration.ttl, expiration.validTo) } } } - def forceReloadTestConfigEngine(config: RawRorConfig, + def forceReloadTestConfigEngine(config: RawRorSettings, ttl: PositiveFiniteDuration) (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, TestConfig.Present]] = { for { @@ -74,9 +73,9 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, value { for { engineExpirationConfig <- reloadEngine(config, ttl).leftMap(IndexConfigReloadWithUpdateError.ReloadError.apply) - testRorConfig = TestRorConfig.Present( - rawConfig = config, - expiration = TestRorConfig.Present.ExpirationConfig( + testRorConfig = TestRorSettings.Present( + rawSettings = config, + expiration = TestRorSettings.Present.ExpirationConfig( ttl = engineExpirationConfig.expirationConfig.ttl, validTo = engineExpirationConfig.expirationConfig.validTo ), @@ -88,7 +87,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, ) .leftWiden[IndexConfigReloadWithUpdateError] } yield TestConfig.Present( - config = engineExpirationConfig.engine.core.rorConfig, + dependencies = engineExpirationConfig.engine.core.dependencies, rawConfig = config, configuredTtl = engineExpirationConfig.expirationConfig.ttl, validTo = engineExpirationConfig.expirationConfig.validTo @@ -106,7 +105,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}") case Left(ReloadError(RawConfigReloadError.RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading tests settings skipped!") - case Left(IndexConfigSavingError(SavingIndexConfigError.CannotSaveConfig)) => + case Left(IndexConfigSavingError(SavingIndexSettingsError.CannotSaveSettings)) => logger.error(s"[${requestId.show}] Saving ROR test settings in index failed") }) } yield reloadResult @@ -119,8 +118,8 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, invalidated <- invalidate(keepPreviousConfiguration = true) result <- invalidated match { case Some(invalidatedEngine) => - val config = TestRorConfig.Present( - rawConfig = invalidatedEngine.config, + val config = TestRorSettings.Present( + rawSettings = invalidatedEngine.config, expiration = ExpirationConfig( ttl = invalidatedEngine.expirationConfig.ttl, validTo = invalidatedEngine.expirationConfig.validTo @@ -147,9 +146,9 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, for { config <- readCurrentTestConfigForUpdate() _ <- updateMocksProvider(mocks) - testRorConfig = TestRorConfig.Present( - rawConfig = config.rawConfig, - expiration = TestRorConfig.Present.ExpirationConfig( + testRorConfig = TestRorSettings.Present( + rawSettings = config.rawConfig, + expiration = TestRorSettings.Present.ExpirationConfig( ttl = config.configuredTtl, validTo = config.validTo ), @@ -183,8 +182,8 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, EitherT.right(Task.delay(boot.authServicesMocksProvider.update(mocks))) } - private def saveConfigInIndex[A](newConfig: TestRorConfig.Present, - onFailure: SavingIndexConfigError => A): EitherT[Task, A, Unit] = { + private def saveConfigInIndex[A](newConfig: TestRorSettings.Present, + onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { EitherT(indexTestConfigManager.save(newConfig, rorConfigurationIndex)) .leftMap(onFailure) } @@ -195,9 +194,9 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, for { loadedConfig <- loadRorConfigFromIndex() config <- loadedConfig match { - case TestRorConfig.NotSet => + case TestRorSettings.NotSet => invalidateTestConfigByIndex[IndexConfigReloadError]() - case TestRorConfig.Present(rawConfig, mocks, expiration) => + case TestRorSettings.Present(rawConfig, mocks, expiration) => for { _ <- reloadEngine(rawConfig, expiration.validTo, expiration.ttl) .leftMap(IndexConfigReloadError.ReloadError.apply) @@ -209,7 +208,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, } } - private def loadRorConfigFromIndex(): EitherT[Task, IndexConfigReloadError, TestRorConfig] = EitherT { + private def loadRorConfigFromIndex(): EitherT[Task, IndexConfigReloadError, TestRorSettings] = EitherT { indexTestConfigManager .load(rorConfigurationIndex) .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) @@ -238,7 +237,7 @@ object TestConfigBasedReloadableEngine { def create(boot: ReadonlyRest, initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexTestConfigManager, + indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorConfigurationIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): TestConfigBasedReloadableEngine = { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index 821505866d..cc7e795309 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -69,8 +69,8 @@ object EsConfigBasedRorSettings { (implicit systemContext: SystemContext) = { EitherT.fromEither[Task] { implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) - new YamlFileBasedConfigLoader(esEnv.configPath) - .loadConfig[XpackSettings](configName = "X-Pack settings") + new YamlFileBasedSettingsLoader(esEnv.configPath) + .loadSettings[XpackSettings](settingsName = "X-Pack settings") .left.map(error => MalformedContent(esEnv.configPath, error.message)) } } @@ -91,13 +91,13 @@ object EsConfigBasedRorSettings { (implicit systemContext: SystemContext) = { EitherT.fromEither[Task] { import decoders.{loadRorCoreStrategyDecoder, rorConfigurationIndexDecoder} - val loader = new YamlFileBasedConfigLoader(esEnv.configPath) + val loader = new YamlFileBasedSettingsLoader(esEnv.configPath) for { strategy <- loader - .loadConfig[LoadingRorCoreStrategy](configName = "ROR loading core settings") + .loadSettings[LoadingRorCoreStrategy](settingsName = "ROR loading core settings") .left.map(error => MalformedContent(esEnv.configPath, error.message)) rorIndex <- loader - .loadConfig[RorConfigurationIndex](configName = "ROR configuration index settings") + .loadSettings[RorConfigurationIndex](settingsName = "ROR configuration index settings") .left.map(error => MalformedContent(esEnv.configPath, error.message)) } yield (strategy, rorIndex) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala similarity index 84% rename from core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala rename to core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala index aa6e83ba3c..53a2b091ab 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.configuration import cats.Eq import io.circe.Json -final case class RawRorConfig(configJson: Json, raw: String) -object RawRorConfig { - implicit val eq: Eq[RawRorConfig] = Eq.fromUniversalEquals +final case class RawRorSettings(settingsJson: Json, raw: String) +object RawRorSettings { + implicit val eq: Eq[RawRorSettings] = Eq.fromUniversalEquals } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala similarity index 71% rename from core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala rename to core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala index 5fde701494..52f6d15572 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorConfigYamlParser.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala @@ -22,27 +22,27 @@ import cats.Show import io.circe.{Json, ParsingFailure} import monix.eval.Task import squants.information.Information -import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError -import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError.{InvalidContent, MoreThanOneRorSection, NoRorSection} +import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError +import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlParser import java.io.StringReader -class RawRorConfigYamlParser(maxSize: Information) { +class RawRorSettingsYamlParser(maxSize: Information) { private val yamlParser: YamlParser = new YamlParser(Some(maxSize)) - def fromFile(file: File): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + def fromFile(file: File): Task[Either[ParsingRorSettingsError, RawRorSettings]] = { fromString(file.contentAsString) } - def fromString(content: String): Task[Either[ParsingRorConfigError, RawRorConfig]] = { + def fromString(content: String): Task[Either[ParsingRorSettingsError, RawRorSettings]] = { val contentResource = Resource.make(Task(new StringReader(content))) { reader => Task(reader.close()) } contentResource.use { reader => Task { handleParseResult(yamlParser.parse(reader)) - .map(RawRorConfig(_, content)) + .map(RawRorSettings(_, content)) } } } @@ -61,15 +61,15 @@ class RawRorConfigYamlParser(maxSize: Information) { } } } -object RawRorConfigYamlParser { +object RawRorSettingsYamlParser { - sealed trait ParsingRorConfigError - object ParsingRorConfigError { - case object NoRorSection extends ParsingRorConfigError - case object MoreThanOneRorSection extends ParsingRorConfigError - final case class InvalidContent(throwable: Throwable) extends ParsingRorConfigError + sealed trait ParsingRorSettingsError + object ParsingRorSettingsError { + case object NoRorSection extends ParsingRorSettingsError + case object MoreThanOneRorSection extends ParsingRorSettingsError + final case class InvalidContent(throwable: Throwable) extends ParsingRorSettingsError - implicit val show: Show[ParsingRorConfigError] = Show.show { + implicit val show: Show[ParsingRorSettingsError] = Show.show { case NoRorSection => "Cannot find any 'readonlyrest' section in settings" case MoreThanOneRorSection => "Only one 'readonlyrest' section is required" case InvalidContent(ex) => s"Settings content is malformed. Details: ${ex.getMessage.show}" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala index e49ff5746e..52d339799a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala @@ -41,7 +41,7 @@ object RorBootSettings extends Logging { private def loadRorBootstrapSettings(configFile: File) (implicit decoder: Decoder[RorBootSettings], systemContext: SystemContext) = { - new YamlFileBasedConfigLoader(configFile).loadConfig[RorBootSettings](configName = "ROR boot settings") + new YamlFileBasedSettingsLoader(configFile).loadSettings[RorBootSettings](settingsName = "ROR boot settings") } final case class RorNotStartedResponse(httpCode: RorNotStartedResponse.HttpCode) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala deleted file mode 100644 index f00e197d48..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorConfigLoading.scala +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import cats.data.EitherT -import cats.implicits.toShow -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexConfigManager} -import tech.beshu.ror.configuration.loader.LoadedRorConfig.IndexParsingError -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.{FileRorConfigLoader, LoadedRorConfig, RorConfigLoader} -import tech.beshu.ror.implicits.* - -object RorConfigLoading extends Logging { - - def loadRorConfigFromIndex(settings: LoadFromIndexSettings, indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error & LoadedRorConfig.LoadingIndexError, LoadedRorConfig[RawRorConfig]]] = { - val rorConfigIndex = settings.rorConfigIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") - EitherT { - indexConfigManager - .load(settings.rorConfigIndex) - .delayExecution(settings.loadingDelay.value.value) - }.map { rawRorConfig => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") - rawRorConfig - } - .bimap(convertIndexError, LoadedRorConfig.apply) - .leftMap { error => - logIndexLoadingError(error) - error - }.value - } - - def loadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { - val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) - .bimap(convertFileError, LoadedRorConfig.apply) - .leftMap { error => - logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") - error - } - .value - } - - def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { - val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorConfigYamlParser(settings.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") - EitherT(new FileRorConfigLoader(rorSettingsFile, rawRorConfigYamlParser).load()) - .bimap(convertFileError, LoadedRorConfig.apply) - .leftMap { error => - logger.error(s"Loading ReadonlyREST from file failed: ${error.toString}") - error - }.value - } -// Free.liftF(LoadRorConfigAction.ForceLoadRorConfigFromFile(settings)) - - private def convertFileError(error: RorConfigLoader.Error[FileRorConfigLoader.Error]): LoadedRorConfig.Error = { - error match { - case ParsingError(error) => - val show = error.show - LoadedRorConfig.FileParsingError(show) - case SpecializedError(FileRorConfigLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) - } - } - - private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]) = - error match { - case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) - case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedRorConfig.IndexNotExist - case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedRorConfig.IndexUnknownStructure - } - - private def logIndexLoadingError[A](error: LoadedRorConfig.LoadingIndexError): Unit = { - error match { - case IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedRorConfig.IndexUnknownStructure => - logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") - case LoadedRorConfig.IndexNotExist => - logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") - } - } - -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index a3657a07d3..0b574ecf52 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -91,7 +91,7 @@ object RorSsl extends Logging { private def loadSslConfigFromFile(configFile: File) (implicit rorSslDecoder: Decoder[Option[RorSsl]], systemContext: SystemContext) = { - new YamlFileBasedConfigLoader(configFile).loadConfig[Option[RorSsl]](configName = "ROR SSL settings") + new YamlFileBasedSettingsLoader(configFile).loadSettings[Option[RorSsl]](settingsName = "ROR SSL settings") } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala deleted file mode 100644 index a11b51e26b..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfigLoading.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import cats.data.EitherT -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexSettings -import tech.beshu.ror.configuration.index.{IndexConfigError, IndexTestConfigManager} -import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.IndexParsingError -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.{LoadedTestRorConfig, RorConfigLoader} -import tech.beshu.ror.implicits.* - -object TestRorConfigLoading extends Logging { - - def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings, - indexConfigManager: IndexTestConfigManager): Task[Either[LoadedTestRorConfig.LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { - val rorConfigIndex = settings.rorConfigIndex - val loadingDelay = settings.loadingDelay - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") - EitherT { - indexConfigManager - .load(rorConfigIndex) - .delayExecution(loadingDelay.value.value) - }.map { testConfig => - testConfig match { - case TestRorConfig.Present(rawConfig, _, _) => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw test config from index: ${rawConfig.raw.show}") - case TestRorConfig.NotSet => - logger.debug("[CLUSTERWIDE SETTINGS] There was no test settings in index. Test settings engine will be not initialized.") - } - testConfig - } - .bimap(convertIndexError, LoadedTestRorConfig.apply) - .leftMap { error => - logIndexLoadingError(error) - error - }.value - } - - private def logIndexLoadingError(error: LoadedTestRorConfig.LoadingIndexError): Unit = { - error match { - case IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedTestRorConfig.IndexUnknownStructure => - logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") - case LoadedTestRorConfig.IndexNotExist => - logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") - } - } - private def convertIndexError(error: RorConfigLoader.Error[IndexConfigError]): LoadedTestRorConfig.LoadingIndexError = - error match { - case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) - case SpecializedError(IndexConfigError.IndexConfigNotExist) => LoadedTestRorConfig.IndexNotExist - case SpecializedError(IndexConfigError.IndexConfigUnknownStructure) => LoadedTestRorConfig.IndexUnknownStructure - } - -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala similarity index 87% rename from core/src/main/scala/tech/beshu/ror/configuration/TestRorConfig.scala rename to core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala index 97a5a9c416..c4342f8f80 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala @@ -21,13 +21,13 @@ import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.{Clock, Instant} -sealed trait TestRorConfig -object TestRorConfig { +sealed trait TestRorSettings +object TestRorSettings { - case object NotSet extends TestRorConfig - final case class Present(rawConfig: RawRorConfig, + case object NotSet extends TestRorSettings + final case class Present(rawSettings: RawRorSettings, mocks: AuthServicesMocks, - expiration: Present.ExpirationConfig) extends TestRorConfig { + expiration: Present.ExpirationConfig) extends TestRorSettings { def isExpired(clock: Clock): Boolean = { expiration.validTo.isBefore(clock.instant()) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala similarity index 74% rename from core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala index f4f67f892b..6c293e5dec 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala @@ -20,37 +20,37 @@ import better.files.File import io.circe.{Decoder, DecodingFailure, Json} import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler -import tech.beshu.ror.accesscontrol.factory.JsonConfigStaticVariableResolver +import tech.beshu.ror.accesscontrol.factory.JsonStaticVariablesResolver import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlParser import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson -final class YamlFileBasedConfigLoader(file: File) - (implicit systemContext: SystemContext) { +final class YamlFileBasedSettingsLoader(file: File) + (implicit systemContext: SystemContext) { private val yamlParser: YamlParser = new YamlParser() - private val jsonConfigResolver = new JsonConfigStaticVariableResolver( + private val jsonStaticVariableResolver = new JsonStaticVariablesResolver( systemContext.envVarsProvider, TransformationCompiler.withoutAliases(systemContext.variablesFunctions) ) - def loadConfig[CONFIG: Decoder](configName: String): Either[MalformedSettings, CONFIG] = { - loadedConfigJson + def loadSettings[SETTINGS: Decoder](settingsName: String): Either[MalformedSettings, SETTINGS] = { + loadedSettingsJson .flatMap { json => - implicitly[Decoder[CONFIG]] + implicitly[Decoder[SETTINGS]] .decodeJson(json) - .left.map(e => MalformedSettings(s"Cannot load ${configName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) + .left.map(e => MalformedSettings(s"Cannot load ${settingsName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) } } - private lazy val loadedConfigJson: Either[MalformedSettings, Json] = { + private lazy val loadedSettingsJson: Either[MalformedSettings, Json] = { file.fileReader { reader => yamlParser .parse(reader) .left.map(e => MalformedSettings(s"Cannot parse file ${file.pathAsString.show} content. Cause: ${e.message.show}")) .flatMap { json => - jsonConfigResolver + jsonStaticVariableResolver .resolve(json) .left.map(e => MalformedSettings(s"Unable to resolve environment variables for file ${file.pathAsString.show}. $e.")) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala deleted file mode 100644 index 3566deb989..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/BaseIndexConfigManager.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.index - -import monix.eval.Task -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.loader.RorConfigLoader -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.SpecializedError - -// todo: it looks like this manager should extend RorConfigLoader -trait BaseIndexConfigManager[A] { - - def load(indexName: RorConfigurationIndex): Task[Either[RorConfigLoader.Error[IndexConfigError], A]] - - def save(config: A, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexConfigError, Unit]] - - protected final def configLoaderError(error: IndexConfigError): Task[Either[SpecializedError[IndexConfigError], A]] = - Task.now(Left(SpecializedError[IndexConfigError](error))) -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala index 64bc97fafb..a66033fb3e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.configuration.index +// todo: what about it? private[index] object Config { object rorSettingsIndexConst { val id = "1" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigError.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigError.scala deleted file mode 100644 index 1a996750fa..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigError.scala +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.index - -import cats.Show - -sealed trait IndexConfigError -object IndexConfigError { - case object IndexConfigNotExist extends IndexConfigError - case object IndexConfigUnknownStructure extends IndexConfigError - - implicit val show: Show[IndexConfigError] = Show.show { - case IndexConfigNotExist => "Cannot find settings index" - case IndexConfigUnknownStructure => s"Unknown structure of index settings" - } -} - -sealed trait SavingIndexConfigError -object SavingIndexConfigError { - case object CannotSaveConfig extends SavingIndexConfigError - - implicit val show: Show[SavingIndexConfigError] = Show.show { - case CannotSaveConfig => "Cannot save settings in index" - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala similarity index 58% rename from core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala index ae7523d819..e271f3ccce 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala @@ -19,19 +19,21 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex -import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} -import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, IndexConfigUnknownStructure} -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.ParsingError +import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.* +import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -final class IndexConfigManager(indexJsonContentService: IndexJsonContentService, - rarRorConfigYamlParser: RawRorConfigYamlParser) - extends BaseIndexConfigManager[RawRorConfig] +final class IndexJsonContentServiceBasedIndexSettingsManager(indexJsonContentService: IndexJsonContentService, + rarRorConfigYamlParser: RawRorSettingsYamlParser) + extends IndexSettingsManager[RawRorSettings] with Logging { - override def load(indexName: RorConfigurationIndex): Task[Either[Error[IndexConfigError], RawRorConfig]] = { + override def load(indexName: RorConfigurationIndex): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { indexJsonContentService .sourceOf(indexName.index, Config.rorSettingsIndexConst.id) .flatMap { @@ -43,23 +45,23 @@ final class IndexConfigManager(indexJsonContentService: IndexJsonContentService, .fromString(rorYamlString) .map(_.left.map(ParsingError.apply)) } - .getOrElse(configLoaderError(IndexConfigUnknownStructure)) + .getOrElse(settingsLoaderError(UnknownStructureOfIndexDocument)) case Left(CannotReachContentSource) => - configLoaderError(IndexConfigNotExist) + settingsLoaderError(IndexNotExist) case Left(ContentNotFound) => - configLoaderError(IndexConfigNotExist) + settingsLoaderError(IndexNotExist) } } - override def save(config: RawRorConfig, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexConfigError, Unit]] = { + override def save(settings: RawRorSettings, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] = { indexJsonContentService .saveContent( rorConfigurationIndex.index, Config.rorSettingsIndexConst.id, - Map(Config.rorSettingsIndexConst.settingsKey -> config.raw) + Map(Config.rorSettingsIndexConst.settingsKey -> settings.raw) ) .map { - _.left.map { case CannotWriteToIndex => SavingIndexConfigError.CannotSaveConfig } + _.left.map { case CannotWriteToIndex => CannotSaveSettings } } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala similarity index 83% rename from core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index 483af8b445..8bef0026b7 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexTestConfigManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -32,12 +32,14 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.L import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorConfigurationIndex, User} -import tech.beshu.ror.configuration.TestRorConfig.Present -import tech.beshu.ror.configuration.index.IndexConfigError.{IndexConfigNotExist, IndexConfigUnknownStructure} -import tech.beshu.ror.configuration.index.IndexTestConfigManager.Const -import tech.beshu.ror.configuration.loader.RorConfigLoader -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{RawRorConfigYamlParser, TestRorConfig} +import tech.beshu.ror.configuration.TestRorSettings.Present +import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexTestSettingsManager.Const +import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.{IndexNotExist, UnknownStructureOfIndexDocument} +import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +import tech.beshu.ror.configuration.loader.RorSettingsLoader +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.{RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} import tech.beshu.ror.syntax.* @@ -49,14 +51,14 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentService, - rarRorConfigYamlParser: RawRorConfigYamlParser) - extends BaseIndexConfigManager[TestRorConfig] +final class IndexJsonContentServiceBasedIndexTestSettingsManager(indexJsonContentService: IndexJsonContentService, + rarRorConfigYamlParser: RawRorSettingsYamlParser) + extends IndexSettingsManager[TestRorSettings] with Logging { - type Error = RorConfigLoader.Error[IndexConfigError] + type Error = RorSettingsLoader.Error[LoadingIndexSettingsError] - override def load(indexName: RorConfigurationIndex): Task[Either[Error, TestRorConfig]] = { + override def load(indexName: RorConfigurationIndex): Task[Either[Error, TestRorSettings]] = { indexJsonContentService .sourceOf(indexName.index, Config.rorTestSettingsIndexConst.id) .flatMap { @@ -64,28 +66,28 @@ final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentServ val properties = source.collect { case (key: String, value: String) => (key, value) } getSettings(properties).value case Left(CannotReachContentSource) => - configLoaderError(IndexConfigNotExist) + settingsLoaderError(IndexNotExist) case Left(ContentNotFound) => - Task.now(Right(TestRorConfig.NotSet)) + Task.now(Right(TestRorSettings.NotSet)) } } - override def save(config: TestRorConfig, - rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexConfigError, Unit]] = { + override def save(settings: TestRorSettings, + rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] = { indexJsonContentService .saveContent( rorConfigurationIndex.index, Config.rorTestSettingsIndexConst.id, - formatSettings(config) + formatSettings(settings) ) .map { - _.left.map { case CannotWriteToIndex => SavingIndexConfigError.CannotSaveConfig } + _.left.map { case CannotWriteToIndex => CannotSaveSettings } } } - private def getSettings(config: Map[String, String]): EitherT[Task, Error, TestRorConfig] = { + private def getSettings(config: Map[String, String]): EitherT[Task, Error, TestRorSettings] = { if (config.isEmpty) { - EitherT.right[Error](Task.now(TestRorConfig.NotSet)).widen[TestRorConfig] + EitherT.right[Error](Task.now(TestRorSettings.NotSet)).widen[TestRorSettings] } else { for { expirationTimeString <- getConfigProperty(config, Const.properties.expirationTime) @@ -101,16 +103,16 @@ final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentServ expirationTtl <- getExpirationTtl(expirationTtlString) mocks <- getMocks(authMocksConfigString) } yield Present( - rawConfig = rawRorConfig, + rawSettings = rawRorConfig, mocks = mocks, expiration = Present.ExpirationConfig(ttl = expirationTtl, validTo = expirationTime) ) } } - private def formatSettings(config: TestRorConfig): Map[String, String] = { + private def formatSettings(config: TestRorSettings): Map[String, String] = { config match { - case TestRorConfig.NotSet => + case TestRorSettings.NotSet => Map.empty case Present(rawConfig, mocks, expiration) => Map( @@ -136,7 +138,7 @@ final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentServ } private def parserError: Error = - SpecializedError[IndexConfigError](IndexConfigUnknownStructure) + SpecializedError[LoadingIndexSettingsError](UnknownStructureOfIndexDocument) private def getInstant(value: String): EitherT[Task, Error, Instant] = { Try(DateTimeFormatter.ISO_DATE_TIME.parse(value)) @@ -243,7 +245,7 @@ final class IndexTestConfigManager(indexJsonContentService: IndexJsonContentServ } -private object IndexTestConfigManager { +private object IndexJsonContentServiceBasedIndexTestSettingsManager { object Const { object properties { val settings = "settings" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala new file mode 100644 index 0000000000..e6f557baa8 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -0,0 +1,59 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.configuration.index + +import cats.Show +import monix.eval.Task +import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.loader.RorSettingsLoader +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError + +// todo: it looks like this manager should extend RorConfigLoader +trait IndexSettingsManager[SETTINGS] { + + def load(indexName: RorConfigurationIndex): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] + + def save(settings: SETTINGS, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] + + // todo: is this ok? + protected final def settingsLoaderError(error: LoadingIndexSettingsError): Task[Either[SpecializedError[LoadingIndexSettingsError], SETTINGS]] = + Task.now(Left(SpecializedError[LoadingIndexSettingsError](error))) +} +object IndexSettingsManager { + + sealed trait LoadingIndexSettingsError + object LoadingIndexSettingsError { + case object IndexNotExist extends LoadingIndexSettingsError + case object UnknownStructureOfIndexDocument extends LoadingIndexSettingsError + + // todo: move to implicits? + implicit val show: Show[LoadingIndexSettingsError] = Show.show { + case IndexNotExist => "Cannot find settings index" + case UnknownStructureOfIndexDocument => s"Unknown structure of index settings" + } + } + + sealed trait SavingIndexSettingsError + object SavingIndexSettingsError { + case object CannotSaveSettings extends SavingIndexSettingsError + + implicit val show: Show[SavingIndexSettingsError] = Show.show { + case CannotSaveSettings => "Cannot save settings in index" + } + } +} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala similarity index 67% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala index a0a4a6b1bf..f8d40b9688 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala @@ -20,16 +20,16 @@ import better.files.File import cats.Show import cats.data.EitherT import monix.eval.Task -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error -import tech.beshu.ror.configuration.loader.RorConfigLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.FileRorConfigLoader.Error.FileNotExist -import tech.beshu.ror.configuration.{RawRorConfig, RawRorConfigYamlParser} +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -class FileRorConfigLoader(rorSettingsFile: File, - rarRorConfigYamlParser: RawRorConfigYamlParser) - extends RorConfigLoader[FileRorConfigLoader.Error] { +class FileRorSettingsLoader(rorSettingsFile: File, + rarRorConfigYamlParser: RawRorSettingsYamlParser) + extends RorSettingsLoader[FileRorSettingsLoader.Error] { - override def load(): Task[Either[Error[FileRorConfigLoader.Error], RawRorConfig]] = { + override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { val file = rorSettingsFile (for { _ <- checkIfFileExist(file) @@ -37,15 +37,15 @@ class FileRorConfigLoader(rorSettingsFile: File, } yield config).value } - private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorConfigLoader.Error], File] = + private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], File] = EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) - private def loadConfigFromFile(file: File): EitherT[Task, Error[FileRorConfigLoader.Error], RawRorConfig] = { + private def loadConfigFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { EitherT(rarRorConfigYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) } } -object FileRorConfigLoader { +object FileRorSettingsLoader { sealed trait Error object Error { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala index 58ef29a240..04533efe8d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala @@ -16,21 +16,29 @@ */ package tech.beshu.ror.configuration.loader +import cats.data.EitherT +import cats.implicits.toShow import monix.eval.Task +import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} -import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.RorConfigLoading.* import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} -import tech.beshu.ror.configuration.index.IndexConfigManager +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +import tech.beshu.ror.configuration.loader.LoadedRorConfig.IndexParsingError +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.implicits.* import scala.concurrent.duration.DurationInt import scala.language.postfixOps -object LoadRawRorConfig { +// todo: indexConfigManager should be passed in constructor? +// todo: refactor methods +object LoadRawRorConfig extends Logging { def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, fallbackFileLoadingSettings: LoadFromFileSettings, - indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, fallback = loadRorConfigFromFile(fallbackFileLoadingSettings), @@ -38,11 +46,12 @@ object LoadRawRorConfig { ) } - def loadFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + def loadFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { forceLoadRorConfigFromFile(settings) } - def loadFromIndex(settings: LoadFromIndexSettings, indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + def loadFromIndex(settings: LoadFromIndexSettings, + indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { for { // todo: is the copy ok? result <- loadRorConfigFromIndex( @@ -63,8 +72,8 @@ object LoadRawRorConfig { } private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]], - indexConfigManager: IndexConfigManager): Task[Either[LoadedRorConfig.Error, LoadedRorConfig[RawRorConfig]]] = { + fallback: Task[Either[LoadedRorConfig.Error, RawRorSettings]], + indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { settings.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) @@ -88,4 +97,78 @@ object LoadRawRorConfig { } yield rawRorConfig } } + + private def loadRorConfigFromIndex(settings: LoadFromIndexSettings, + indexConfigManager: IndexSettingsManager[RawRorSettings]) = { + val rorConfigIndex = settings.rorConfigIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") + EitherT { + indexConfigManager + .load(settings.rorConfigIndex) + .delayExecution(settings.loadingDelay.value.value) + }.map { rawRorConfig => + logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") + rawRorConfig + } + .leftMap { error => + val newError = convertIndexError(error) + logIndexLoadingError(newError) + newError + } + .value + } + + private def loadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { + val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") + EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + .leftMap { error => + val newError = convertFileError(error) + logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") + newError + } + .value + } + + private def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { + val rorSettingsFile = settings.rorSettingsFile + val rawRorConfigYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") + EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + .leftMap { error => + val newError = convertFileError(error) + logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") + newError + } + .value + } + + private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadedRorConfig.Error = { + error match { + case ParsingError(error) => + val show = error.show + LoadedRorConfig.FileParsingError(show) + case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) + } + } + + private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]) = + error match { + case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadedRorConfig.IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadedRorConfig.IndexUnknownStructure + } + + private def logIndexLoadingError[A](error: LoadedRorConfig.LoadingIndexError): Unit = { + error match { + case IndexParsingError(message) => + logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") + case LoadedRorConfig.IndexUnknownStructure => + logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") + case LoadedRorConfig.IndexNotExist => + logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") + } + } + } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala index ad39536c42..752e3d9f39 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala @@ -16,22 +16,27 @@ */ package tech.beshu.ror.configuration.loader +import cats.data.EitherT import monix.eval.Task +import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} -import tech.beshu.ror.configuration.TestRorConfig -import tech.beshu.ror.configuration.TestRorConfigLoading.* -import tech.beshu.ror.configuration.index.IndexTestConfigManager -import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.LoadingIndexError +import tech.beshu.ror.configuration.TestRorSettings +import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.{IndexParsingError, LoadingIndexError} +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.implicits.* import scala.concurrent.duration.DurationInt import scala.language.postfixOps -object LoadRawTestRorConfig { + +object LoadRawTestRorConfig extends Logging { def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackConfig: TestRorConfig, - indexConfigManager: IndexTestConfigManager): Task[Either[LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { + fallbackConfig: TestRorSettings, + indexConfigManager: IndexSettingsManager[TestRorSettings]): Task[Either[LoadingIndexError, TestRorSettings]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, fallback = fallbackConfig, @@ -40,11 +45,11 @@ object LoadRawTestRorConfig { } private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: TestRorConfig, - indexConfigManager: IndexTestConfigManager): Task[Either[LoadingIndexError, LoadedTestRorConfig[TestRorConfig]]] = { + fallback: TestRorSettings, + indexConfigManager: IndexSettingsManager[TestRorSettings]): Task[Either[LoadingIndexError, TestRorSettings]] = { settings.loadingAttemptsCount.value.value match { case 0 => - Task.now(Right(LoadedTestRorConfig[TestRorConfig](fallback))) + Task.now(Right(fallback)) case attemptsCount => for { result <- loadTestRorConfigFromIndex( @@ -68,4 +73,50 @@ object LoadRawTestRorConfig { } yield rawRorConfig } } + + private def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings, + indexConfigManager: IndexSettingsManager[TestRorSettings]) = { + val rorConfigIndex = settings.rorConfigIndex + val loadingDelay = settings.loadingDelay + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") + EitherT { + indexConfigManager + .load(rorConfigIndex) + .delayExecution(loadingDelay.value.value) + } + .map { testConfig => + testConfig match { + case TestRorSettings.Present(rawConfig, _, _) => + logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw test config from index: ${rawConfig.raw.show}") + case TestRorSettings.NotSet => + logger.debug("[CLUSTERWIDE SETTINGS] There was no test settings in index. Test settings engine will be not initialized.") + } + testConfig + } + .leftMap { error => + val newError = convertIndexError(error) + logIndexLoadingError(newError) + newError + } + .value + } + + private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadedTestRorConfig.LoadingIndexError = + error match { + case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadedTestRorConfig.IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadedTestRorConfig.IndexUnknownStructure + } + + private def logIndexLoadingError(error: LoadedTestRorConfig.LoadingIndexError): Unit = { + error match { + case IndexParsingError(message) => + logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") + case LoadedTestRorConfig.IndexUnknownStructure => + logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") + case LoadedTestRorConfig.IndexNotExist => + logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") + } + } + } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala similarity index 69% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala index 7759bf8e9c..cd5c238f14 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorConfigLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala @@ -18,23 +18,24 @@ package tech.beshu.ror.configuration.loader import cats.Show import monix.eval.Task -import tech.beshu.ror.configuration.RawRorConfig -import tech.beshu.ror.configuration.RawRorConfigYamlParser.ParsingRorConfigError +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError -trait RorConfigLoader[SPECIALIZED_ERROR] { +trait RorSettingsLoader[SPECIALIZED_ERROR] { - def load(): Task[Either[RorConfigLoader.Error[SPECIALIZED_ERROR], RawRorConfig]] + def load(): Task[Either[RorSettingsLoader.Error[SPECIALIZED_ERROR], RawRorSettings]] } -object RorConfigLoader { +object RorSettingsLoader { sealed trait Error[+SPECIALIZED_ERROR] object Error { - final case class ParsingError(error: ParsingRorConfigError) extends Error[Nothing] + final case class ParsingError(error: ParsingRorSettingsError) extends Error[Nothing] final case class SpecializedError[ERROR](error: ERROR) extends Error[ERROR] + // todo: move? implicit def show[E: Show]: Show[Error[E]] = Show.show { - case ParsingError(error) => Show[ParsingRorConfigError].show(error) + case ParsingError(error) => Show[ParsingRorSettingsError].show(error) case SpecializedError(error) => Show[E].show(error) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala index 5b3d7f2b1b..a6c8cbeab3 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala @@ -18,8 +18,7 @@ package tech.beshu.ror.configuration.loader import java.nio.file.Path -// todo: do we need this wrapper? -final case class LoadedRorConfig[A](value: A) +// todo: move? object LoadedRorConfig { sealed trait Error @@ -32,7 +31,6 @@ object LoadedRorConfig { case object IndexNotExist extends LoadedRorConfig.Error with LoadingIndexError } -final case class LoadedTestRorConfig[A](value: A) object LoadedTestRorConfig { sealed trait LoadingIndexError diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala deleted file mode 100644 index a13d1d0fa7..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/package.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration - -import cats.Functor - -package object loader { - - implicit val functorLoadedConfig: Functor[LoadedRorConfig] = new Functor[LoadedRorConfig] { - override def map[A, B](fa: LoadedRorConfig[A])(f: A => B): LoadedRorConfig[B] = LoadedRorConfig(f(fa.value)) - } -} diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 20343eb9fe..544ae3e7d6 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.providers.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -48,7 +48,7 @@ trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { lazy val acl: AccessControlList = { val aclEngineT = for { - config <- RawRorConfig + config <- RawRorSettings .fromString(configYaml) .map(_.fold(err => throw new IllegalStateException(err.show), identity)) core <- factory diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index 367f7c15df..a00a92f2db 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -23,6 +23,7 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink.Config import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider @@ -33,7 +34,7 @@ import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCre import tech.beshu.ror.accesscontrol.factory.{Core, RawRorConfigBasedCoreFactory} import tech.beshu.ror.audit.adapters.DeprecatedAuditLogSerializerAdapter import tech.beshu.ror.audit.instances.{DefaultAuditLogSerializer, QueryAuditLogSerializer} -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} import tech.beshu.ror.es.EsVersion import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.utils.TestsUtils.* @@ -177,7 +178,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(3) val sink1 = auditingSettings.auditSinks.head @@ -834,7 +835,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(3) val sink1 = auditingSettings.auditSinks.head @@ -893,7 +894,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(2) val sink1 = auditingSettings.auditSinks.head @@ -1676,7 +1677,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertSettingsNoPresent(config: RawRorConfig): Unit = { + private def assertSettingsNoPresent(config: RawRorSettings): Unit = { val core = factory() .createCoreFrom( config, @@ -1686,10 +1687,10 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, None))) => } + inside(core) { case Right(Core(_, RorDependencies(_, _, _, None))) => } } - private def assertSettings(config: RawRorConfig, expectedConfigs: NonEmptyList[AuditSink]): Unit = { + private def assertSettings(config: RawRorSettings, expectedConfigs: NonEmptyList[AuditSink]): Unit = { val core = factory() .createCoreFrom( config, @@ -1699,13 +1700,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(settings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(settings)))) => settings.auditSinks should be(expectedConfigs) } } - private def assertIndexBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorConfig, + private def assertIndexBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, expectedIndexName: NonEmptyString, expectedAuditCluster: AuditCluster) = { val core = factory() @@ -1717,7 +1718,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1733,7 +1734,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertDataStreamAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorConfig, + private def assertDataStreamAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, expectedDataStreamName: NonEmptyString, expectedAuditCluster: AuditCluster, esVersion: EsVersion = defaultEsVersionForTests) = { @@ -1746,7 +1747,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1762,7 +1763,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertLogBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorConfig, + private def assertLogBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, expectedLoggerName: NonEmptyString) = { val core = factory() .createCoreFrom( @@ -1773,7 +1774,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorConfig(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1788,7 +1789,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertInvalidSettings(config: RawRorConfig, + private def assertInvalidSettings(config: RawRorSettings, expectedErrorMessage: String, esVersion: EsVersion = defaultEsVersionForTests): Unit = { val core = factory(esVersion) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index ab733bcfe2..c093ebcd20 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockHttpClientsFactoryWithFixedHttpClient, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.TestsUtils.* @@ -482,7 +482,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } } - private def createCore(config: RawRorConfig, + private def createCore(config: RawRorSettings, clientsFactory: HttpClientsFactory = MockHttpClientsFactory) = { factory .createCoreFrom( diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index e3b4200583..3ce29fbaa6 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorConfigurationIndex} import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.MockHttpClientsFactory import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers @@ -365,13 +365,13 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { val rorConfig = rorConfigFromUnsafe(config) inside(createCore(config = rorConfig, mocksProvider = mocksProvider)) { case Right(core) => - core.rorConfig.impersonationWarningsReader + core.dependencies.impersonationWarningsReader } } private implicit val dummyRequestID: RequestId = RequestId("dummy") - private def createCore(config: RawRorConfig, + private def createCore(config: RawRorSettings, clientsFactory: HttpClientsFactory = MockHttpClientsFactory, mocksProvider: MocksProvider) = { factory diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index 5690b764e8..eca282accb 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -24,7 +24,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorConfigurationIndex, User} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers @@ -202,7 +202,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { val rorConfig = rorConfigFromUnsafe(config) inside(createCore(rorConfig, new UnboundidLdapConnectionPoolProvider())) { case Right(core) => - core.rorConfig.localUsers should be(allUsersResolved(Set( + core.dependencies.localUsers should be(allUsersResolved(Set( User.Id("admin"), User.Id("cartman"), User.Id("Bìlbö Bággįnš"), User.Id("bong"), User.Id("morgan") ))) } @@ -299,11 +299,11 @@ class LocalUsersTest extends AnyWordSpec with Inside { val rorConfig = rorConfigFromUnsafe(config) inside(createCore(rorConfig)) { case Right(core) => - core.rorConfig.localUsers should be(expected) + core.dependencies.localUsers should be(expected) } } - private def createCore(config: RawRorConfig, + private def createCore(config: RawRorSettings, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider = MockLdapConnectionPoolProvider, clientsFactory: HttpClientsFactory = MockHttpClientsFactory) = { factory diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 99ceb6c1c8..da8158ca74 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -45,9 +45,9 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, TestConfig} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.RorConfig.NoOpImpersonationWarningsReader +import tech.beshu.ror.configuration.RorDependencies.NoOpImpersonationWarningsReader import tech.beshu.ror.configuration.index.SavingIndexConfigError -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound, WriteError} @@ -181,7 +181,7 @@ class ReadonlyRestStartingTests createCoreResult = Task .sleep(100 millis) - .map(_ => Right(Core(mockEnabledAccessControl, RorConfig.disabled))) // very long creation + .map(_ => Right(Core(mockEnabledAccessControl, RorDependencies.noOp))) // very long creation ) mockIndexJsonContentManagerSaveCall( mockedIndexJsonContentManager, @@ -424,7 +424,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -915,7 +915,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -952,7 +952,7 @@ class ReadonlyRestStartingTests }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -978,7 +978,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (200 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 @@ -1016,7 +1016,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -1042,7 +1042,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 @@ -1080,7 +1080,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -1263,7 +1263,7 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( TestConfig.Present( - config = RorConfig.disabled, + dependencies = RorDependencies.noOp, rawConfig = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp @@ -1324,7 +1324,7 @@ class ReadonlyRestStartingTests mock[CoreFactory], "/boot_tests/forced_file_loading_with_audit/readonlyrest.yml", mockEnabledAccessControl, - RorConfig(RorConfig.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader, Some(AuditingTool.Settings( + RorConfig(RorDependencies.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader, Some(AuditingTool.Settings( NonEmptyList.of( AuditSink.Enabled(dataStreamSinkConfig1), AuditSink.Enabled(dataStreamSinkConfig2)) @@ -1461,31 +1461,31 @@ class ReadonlyRestStartingTests private def mockCoreFactory(mockedCoreFactory: CoreFactory, resourceFileName: String, accessControlMock: AccessControlList = mockEnabledAccessControl, - rorConfig: RorConfig = RorConfig.disabled): CoreFactory = { - mockCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName), accessControlMock, rorConfig) + dependencies: RorDependencies = RorDependencies.noOp): CoreFactory = { + mockCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName), accessControlMock, dependencies) } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorConfig, + rawRorConfig: RawRorSettings, accessControlMock: AccessControlList, - rorConfig: RorConfig): CoreFactory = { + dependencies: RorDependencies): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorConfig, _, _, _, _) => config == rawRorConfig + (config: RawRorSettings, _, _, _, _) => config == rawRorConfig }) .once() - .returns(Task.now(Right(Core(accessControlMock, rorConfig)))) + .returns(Task.now(Right(Core(accessControlMock, dependencies)))) mockedCoreFactory } - private def disabledRorConfig = RorConfig.disabled + private def disabledRorConfig = RorDependencies.noOp private def mockCoreFactory(mockedCoreFactory: CoreFactory, resourceFileName: String, createCoreResult: Task[Either[NonEmptyList[CoreCreationError], Core]]) = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorConfig, _, _, _, _) => config == rorConfigFromResource(resourceFileName) + (config: RawRorSettings, _, _, _, _) => config == rorConfigFromResource(resourceFileName) }) .once() .returns(createCoreResult) @@ -1498,10 +1498,10 @@ class ReadonlyRestStartingTests } private def mockFailedCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorConfig): CoreFactory = { + rawRorConfig: RawRorSettings): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorConfig, _, _, _, _) => config == rawRorConfig + (config: RawRorSettings, _, _, _, _) => config == rawRorConfig }) .once() .returns(Task.now(Left(NonEmptyList.one(CoreCreationError.GeneralReadonlyrestSettingsError(Message("failed")))))) diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index 5de2b57ef1..b618b5111f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} import tech.beshu.ror.boot.RorInstance.TestConfig import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.{RawRorConfig, RorConfig} +import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -234,13 +234,13 @@ class RorIndexTest extends AnyWordSpec } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorConfig): CoreFactory = { + rawRorConfig: RawRorSettings): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorConfig, _, _, _, _) => config == rawRorConfig + (config: RawRorSettings, _, _, _, _) => config == rawRorConfig }) .once() - .returns(Task.now(Right(Core(mockAccessControl, RorConfig.disabled)))) + .returns(Task.now(Right(Core(mockAccessControl, RorDependencies.noOp)))) mockedCoreFactory } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala similarity index 96% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala index 52e5c1e43f..16ed02e98f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorConfigTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala @@ -24,7 +24,7 @@ import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction.* -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} import tech.beshu.ror.configuration.loader.{LoadRawRorConfig, LoadedRorConfig} @@ -35,8 +35,8 @@ import java.nio.file.Paths import scala.concurrent.duration.* import scala.language.{existentials, postfixOps} -class LoadRawRorConfigTest extends AnyWordSpec with EitherValues{ - import LoadRawRorConfigTest.* +class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ + import LoadRawRorSettingsTest.* "Free monad loader program" should { "load forced file" in { val steps = List( @@ -45,7 +45,7 @@ class LoadRawRorConfigTest extends AnyWordSpec with EitherValues{ val compiler = IdCompiler.instance(steps) val program = LoadRawRorConfig.loadFromFile(esEnv.configPath) val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, ForcedFileConfig[RawRorConfig]]] + val ffc = result.asInstanceOf[Right[Nothing, ForcedFileConfig[RawRorSettings]]] ffc.value.value shouldEqual rawRorConfig } "load successfully from index" in { @@ -62,7 +62,7 @@ class LoadRawRorConfigTest extends AnyWordSpec with EitherValues{ fallbackConfigFilePath = esEnv.configPath ) val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorConfig]]] + val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] ffc.value.value shouldEqual rawRorConfig } "load successfully from index, after failure" in { @@ -81,7 +81,7 @@ class LoadRawRorConfigTest extends AnyWordSpec with EitherValues{ fallbackConfigFilePath = esEnv.configPath ) val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorConfig]]] + val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] ffc.value.value shouldEqual rawRorConfig } "load from file when index not exist" in { @@ -141,10 +141,10 @@ class LoadRawRorConfigTest extends AnyWordSpec with EitherValues{ } } } -object LoadRawRorConfigTest { +object LoadRawRorSettingsTest { private val esEnv = EsEnv(Paths.get("unused_file_path"), Paths.get("unused_file_path"), defaultEsVersionForTests) - private val rawRorConfig = RawRorConfig(Json.False, "forced file config") + private val rawRorConfig = RawRorSettings(Json.False, "forced file config") private val rorConfigurationIndex = RorConfigurationIndex(IndexName.Full("rorConfigurationIndex")) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala similarity index 91% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala index c24061ce6e..d75105a3f4 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorConfigLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala @@ -22,9 +22,9 @@ import io.circe.Decoder import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.configuration.{Environment, YamlFileBasedConfigLoader} +import tech.beshu.ror.configuration.{Environment, YamlFileBasedSettingsLoader} -class YamlFileBasedRorConfigLoaderTest extends AnyWordSpec with Inside { +class YamlFileBasedRorSettingsLoaderTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = new Environment( envVarsProvider = name => @@ -59,10 +59,10 @@ class YamlFileBasedRorConfigLoaderTest extends AnyWordSpec with Inside { private def loadFromTempFile[A: Decoder](content: String) = tempFile(content).map { file => createFileConfigLoader(file) - .loadConfig[A]("TEST") + .loadSettings[A]("TEST") }.get() private def tempFile(content: String) = File.temporaryFile().map(_.write(content)) - private def createFileConfigLoader(file: File) = new YamlFileBasedConfigLoader(file) + private def createFileConfigLoader(file: File) = new YamlFileBasedSettingsLoader(file) } diff --git a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala index f2ebbb955c..bb0813ef39 100644 --- a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala +++ b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala @@ -50,7 +50,7 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.Header.Name import tech.beshu.ror.accesscontrol.domain.KibanaApp.KibanaAppRegex import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern -import tech.beshu.ror.configuration.RawRorConfig +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.EsVersion import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.js.{JsCompiler, MozillaJsCompiler} @@ -379,17 +379,17 @@ object TestsUtils { def nel: NonEmptyList[T] = NonEmptyList.one(value) } - def rorConfigFromUnsafe(yamlContent: String): RawRorConfig = { + def rorConfigFromUnsafe(yamlContent: String): RawRorSettings = { rorConfigFrom(yamlContent).toOption.get } - def rorConfigFrom(yamlContent: String): Either[ParsingFailure, RawRorConfig] = { + def rorConfigFrom(yamlContent: String): Either[ParsingFailure, RawRorSettings] = { rorYamlParser .parse(yamlContent) - .map(json => RawRorConfig(json, yamlContent)) + .map(json => RawRorSettings(json, yamlContent)) } - def rorConfigFromResource(resource: String): RawRorConfig = { + def rorConfigFromResource(resource: String): RawRorSettings = { rorConfigFromUnsafe { getResourceContent(resource) } From 36dfbcbdc138cd3c8386cf9bbceeda9386bc2242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 10 Jul 2025 16:17:10 +0200 Subject: [PATCH 012/103] refactoring --- .../accesscontrol/factory/CoreFactory.scala | 16 +-- .../scala/tech/beshu/ror/api/ConfigApi.scala | 7 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 66 +++++----- .../tech/beshu/ror/boot/RorInstance.scala | 22 ++-- .../boot/engines/BaseReloadableEngine.scala | 32 ++--- .../MainConfigBasedReloadableEngine.scala | 12 +- .../TestConfigBasedReloadableEngine.scala | 22 ++-- .../ror/configuration/index/Config.scala | 29 ----- ...erviceBasedIndexMainSettingsManager.scala} | 26 ++-- ...ServiceBasedIndexTestSettingsManager.scala | 19 ++- .../index/IndexSettingsManager.scala | 6 +- ...fig.scala => RorMainSettingsManager.scala} | 118 ++++++++---------- .../loader/RorSettingsLoader.scala | 1 + ...nfig.scala => RorTestSettingsLoader.scala} | 51 ++++---- .../ror/configuration/loader/domain.scala | 40 ------ .../LoadRawRorSettingsTest.scala | 14 +-- 16 files changed, 203 insertions(+), 278 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala rename core/src/main/scala/tech/beshu/ror/configuration/index/{IndexJsonContentServiceBasedIndexSettingsManager.scala => IndexJsonContentServiceBasedIndexMainSettingsManager.scala} (70%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{LoadRawRorConfig.scala => RorMainSettingsManager.scala} (53%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{LoadRawTestRorConfig.scala => RorTestSettingsLoader.scala} (73%) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index ee63137243..37a271e30a 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -62,8 +62,8 @@ final case class Core(accessControl: AccessControlList, auditingSettings: Option[AuditingTool.Settings]) trait CoreFactory { - def createCoreFrom(config: RawRorSettings, - rorIndexNameConfiguration: RorConfigurationIndex, + def createCoreFrom(rorSettings: RawRorSettings, + rorSettingsIndex: RorConfigurationIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] @@ -73,22 +73,22 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) (implicit systemContext: SystemContext) extends CoreFactory with Logging { - override def createCoreFrom(config: RawRorSettings, - rorIndexNameConfiguration: RorConfigurationIndex, + override def createCoreFrom(rorSettings: RawRorSettings, + rorSettingsIndex: RorConfigurationIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] = { - config.settingsJson \\ Attributes.rorSectionName match { + rorSettings.settingsJson \\ Attributes.rorSectionName match { case Nil => createCoreFromRorSection( - config.settingsJson, - rorIndexNameConfiguration, + rorSettings.settingsJson, + rorSettingsIndex, httpClientFactory, ldapConnectionPoolProvider, mocksProvider ) case rorSection :: Nil => createCoreFromRorSection( rorSection, - rorIndexNameConfiguration, + rorSettingsIndex, httpClientFactory, ldapConnectionPoolProvider, mocksProvider diff --git a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala index fda45983eb..4efbbba86d 100644 --- a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala @@ -22,7 +22,7 @@ import cats.implicits.* import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.api.ConfigApi.* import tech.beshu.ror.api.ConfigApi.ConfigRequest.Type import tech.beshu.ror.api.ConfigApi.ConfigResponse.* @@ -39,8 +39,7 @@ import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class ConfigApi(rorInstance: RorInstance, rawRorConfigYamlParser: RawRorSettingsYamlParser, indexConfigManager: IndexSettingsManager[RawRorSettings], - fileConfigLoader: FileRorSettingsLoader, - rorConfigurationIndex: RorConfigurationIndex) + fileConfigLoader: FileRorSettingsLoader) extends Logging { import ConfigApi.Utils.* @@ -98,7 +97,7 @@ class ConfigApi(rorInstance: RorInstance, private def provideRorIndexConfig(): Task[ConfigResponse] = { indexConfigManager - .load(rorConfigurationIndex) + .load() .map { case Right(config) => ProvideIndexConfig.Config(config.raw) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 6d08556b3e..b0f2b01342 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -25,7 +25,6 @@ import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.audit.{AuditingTool, LoggingContext} import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MutableMocksProviderWithCachePerRequest} -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason @@ -55,10 +54,12 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { rorYamlParser <- lift(new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) - indexConfigManager <- lift(new IndexJsonContentServiceBasedIndexSettingsManager(indexContentService, rorYamlParser)) - indexTestConfigManager <- lift(new IndexJsonContentServiceBasedIndexTestSettingsManager(indexContentService, rorYamlParser)) - loadedRorConfig <- loadRorConfig(esConfig, indexConfigManager) - loadedTestRorConfig <- loadRorTestConfig(esConfig, indexTestConfigManager) + indexConfigManager <- lift(new IndexJsonContentServiceBasedIndexMainSettingsManager(esConfig.rorConfigIndex, indexContentService, rorYamlParser)) + rorMainSettingsLoader <- lift(new RorMainSettingsManager(indexConfigManager)) + indexTestConfigManager <- lift(new IndexJsonContentServiceBasedIndexTestSettingsManager(esConfig.rorConfigIndex, indexContentService, rorYamlParser)) + rorTestSettingsLoader <- lift(new RorTestSettingsLoader(indexTestConfigManager)) + loadedRorConfig <- loadRorConfig(esConfig, rorMainSettingsLoader) + loadedTestRorConfig <- loadRorTestConfig(esConfig, rorTestSettingsLoader) instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig, indexConfigManager, indexTestConfigManager) } yield instance).value } @@ -68,23 +69,23 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadRorConfig(esConfig: EsConfigBasedRorSettings, - indexConfigManager: IndexSettingsManager[RawRorSettings]): EitherT[Task, StartingFailure, RawRorSettings] = { + rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - EitherT(LoadRawRorConfig.loadFromFile(settings)) + EitherT(rorSettingsLoader.loadFromFile(settings)) .leftMap(toStartingFailure) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => // todo: move // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - EitherT(LoadRawRorConfig.loadFromIndexWithFileFallback(settings, fallbackSettings, indexConfigManager)) + EitherT(rorSettingsLoader.loadFromIndexWithFileFallback(settings, fallbackSettings)) .leftMap(toStartingFailure) } } private def loadRorTestConfig(esConfig: EsConfigBasedRorSettings, - indexTestConfigManager: IndexSettingsManager[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { + rorSettingsLoader: RorTestSettingsLoader): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) @@ -95,49 +96,48 @@ class ReadonlyRest(coreFactory: CoreFactory, // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) EitherT { - LoadRawTestRorConfig.loadFromIndexWithFallback( + rorSettingsLoader.loadFromIndexWithFallback( indexLoadingSettings = settings, - fallbackConfig = notSetTestRorConfig, - indexTestConfigManager + fallbackConfig = notSetTestRorConfig ) }.leftFlatMap { - case LoadedTestRorConfig.IndexParsingError(message) => + case RorTestSettingsLoader.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) - case LoadedTestRorConfig.IndexUnknownStructure => + case RorTestSettingsLoader.IndexUnknownStructure => logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) - case LoadedTestRorConfig.IndexNotExist => + case RorTestSettingsLoader.IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) } } } - private def toStartingFailure(error: LoadedRorConfig.Error) = { + private def toStartingFailure(error: RorMainSettingsManager.Error) = { error match { - case LoadedRorConfig.FileParsingError(message) => + case RorMainSettingsManager.FileParsingError(message) => StartingFailure(message) - case LoadedRorConfig.FileNotExist(path) => + case RorMainSettingsManager.FileNotExist(path) => StartingFailure(s"Cannot find settings file: ${path.show}") - case LoadedRorConfig.IndexParsingError(message) => + case RorMainSettingsManager.IndexParsingError(message) => StartingFailure(message) - case LoadedRorConfig.IndexUnknownStructure => + case RorMainSettingsManager.IndexUnknownStructure => StartingFailure(s"Settings index is malformed") - case LoadedRorConfig.IndexNotExist => + case RorMainSettingsManager.IndexNotExist => StartingFailure(s"Settings index doesn't exist") } } private def startRor(esConfig: EsConfigBasedRorSettings, - loadedConfig: RawRorSettings, + loadedRorSettings: RawRorSettings, loadedTestRorConfig: TestRorSettings, indexConfigManager: IndexSettingsManager[RawRorSettings], indexTestConfigManager: IndexSettingsManager[TestRorSettings]) = { for { - mainEngine <- EitherT(loadRorEngine(loadedConfig, esConfig.rorConfigIndex)) + mainEngine <- EitherT(loadRorEngine(loadedRorSettings, esConfig)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) - rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedConfig) + rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedRorSettings) } yield rorInstance } @@ -152,20 +152,20 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testConfig: TestRorSettings.Present) = { + private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testSettings: TestRorSettings.Present) = { for { - _ <- Task.delay(authServicesMocksProvider.update(testConfig.mocks)) - testEngine <- loadRorEngine(testConfig.rawSettings, esConfig.rorConfigIndex) + _ <- Task.delay(authServicesMocksProvider.update(testSettings.mocks)) + testEngine <- loadRorEngine(testSettings.rawSettings, esConfig) .map { case Right(loadedEngine) => TestEngine.Configured( engine = loadedEngine, - config = testConfig.rawSettings, - expiration = expirationConfig(testConfig.expiration) + config = testSettings.rawSettings, + expiration = expirationConfig(testSettings.expiration) ) case Left(startingFailure) => logger.error(s"Unable to start test engine. Cause: ${startingFailure.message.show}. Test settings engine will be marked as invalidated.") - TestEngine.Invalidated(testConfig.rawSettings, expirationConfig(testConfig.expiration)) + TestEngine.Invalidated(testSettings.rawSettings, expirationConfig(testSettings.expiration)) } } yield testEngine } @@ -201,14 +201,14 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private[ror] def loadRorEngine(config: RawRorSettings, - rorIndexNameConfiguration: RorConfigurationIndex): Task[Either[StartingFailure, Engine]] = { + private[ror] def loadRorEngine(rorSettings: RawRorSettings, + esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, Engine]] = { val httpClientsFactory = new AsyncHttpClientsFactory val ldapConnectionPoolProvider = new UnboundidLdapConnectionPoolProvider EitherT( coreFactory - .createCoreFrom(config, rorIndexNameConfiguration, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) + .createCoreFrom(rorSettings, esConfig.rorConfigIndex, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) ) .flatMap(core => createEngine(httpClientsFactory, ldapConnectionPoolProvider, core)) .semiflatTap { engine => diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 9fec1e0630..0d48f9d2b5 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -37,7 +37,7 @@ import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSett import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error import tech.beshu.ror.configuration.loader.FileRorSettingsLoader -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -45,13 +45,14 @@ import java.time.Instant class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, + esConfig: EsConfigBasedRorSettings, initialEngine: ReadonlyRest.MainEngine, mainReloadInProgress: Semaphore[Task], initialTestEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], indexConfigManager: IndexSettingsManager[RawRorSettings], indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorSettingsIndex: RorConfigurationIndex, + rorSettingsIndex: RorConfigurationIndex, // todo: do we need this? rorSettingsFile: File, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, @@ -72,17 +73,17 @@ class RorInstance private(boot: ReadonlyRest, private val aMainConfigEngine = new MainConfigBasedReloadableEngine( boot, + esConfig, (initialEngine.engine, initialEngine.config), mainReloadInProgress, - indexConfigManager, - rorSettingsIndex, + indexConfigManager ) private val anTestConfigEngine = TestConfigBasedReloadableEngine.create( boot, + esConfig, initialTestEngine, testReloadInProgress, - indexTestConfigManager, - rorSettingsIndex + indexTestConfigManager ) private val rarRorConfigYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) @@ -91,8 +92,7 @@ class RorInstance private(boot: ReadonlyRest, rorInstance = this, rarRorConfigYamlParser, indexConfigManager, - new FileRorSettingsLoader(rorSettingsFile, rarRorConfigYamlParser), - rorSettingsIndex + new FileRorSettingsLoader(rorSettingsFile, rarRorConfigYamlParser) ) private val authMockRestApi = new AuthMockApi(rorInstance = this) @@ -274,6 +274,7 @@ object RorInstance { } def createWithPeriodicIndexCheck(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, indexConfigManager: IndexSettingsManager[RawRorSettings], @@ -284,10 +285,11 @@ object RorInstance { rorSettingsIndex: RorConfigurationIndex) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) + create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, indexConfigManager: IndexSettingsManager[RawRorSettings], @@ -301,6 +303,7 @@ object RorInstance { } private def create(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, mode: RorInstance.Mode, engine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, @@ -316,6 +319,7 @@ object RorInstance { isTestReloadInProgressSemaphore <- Semaphore[Task](1) } yield new RorInstance( boot = boot, + esConfig = esConfig, mode = mode, initialEngine = engine, mainReloadInProgress = isReloadInProgressSemaphore, diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index d4d84d945d..9f559eb0b4 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -24,14 +24,14 @@ import monix.execution.atomic.{Atomic, AtomicAny} import monix.execution.{Cancelable, Scheduler} import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.Engine import tech.beshu.ror.boot.RorInstance.RawConfigReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.* @@ -41,9 +41,9 @@ import scala.language.postfixOps private[engines] abstract class BaseReloadableEngine(val name: String, boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, initialEngine: InitialEngine, - reloadInProgress: Semaphore[Task], - rorConfigurationIndex: RorConfigurationIndex) + reloadInProgress: Semaphore[Task]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -127,9 +127,9 @@ private[engines] abstract class BaseReloadableEngine(val name: String, protected final def currentEngineState: EngineState = currentEngine.get() - protected def reloadEngine(newConfig: RawRorSettings) + protected def reloadEngine(rorSettings: RawRorSettings) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { - reloadEngineWithoutTtl(newConfig) + reloadEngineWithoutTtl(rorSettings) } protected def reloadEngine(newConfig: RawRorSettings, @@ -183,19 +183,19 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } yield expirationConfig } - private def reloadEngineWithoutTtl(newConfig: RawRorSettings) + private def reloadEngineWithoutTtl(rorSettings: RawRorSettings) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { for { - _ <- canBeReloaded(newConfig) - _ <- runReload(newConfig, None) + _ <- canBeReloaded(rorSettings) + _ <- runReload(rorSettings, None) } yield () } - private def runReload(newConfig: RawRorSettings, + private def runReload(rorSettings: RawRorSettings, configExpiration: Option[UpdatedConfigExpiration]) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, EngineWithConfig] = { for { - newEngineWithConfig <- reloadWith(newConfig, configExpiration) + newEngineWithConfig <- reloadWith(rorSettings, configExpiration) _ <- replaceCurrentEngine(newEngineWithConfig) } yield newEngineWithConfig } @@ -251,14 +251,14 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def reloadWith(newConfig: RawRorSettings, + private def reloadWith(rorSettings: RawRorSettings, configExpiration: Option[UpdatedConfigExpiration]): EitherT[Task, RawConfigReloadError, EngineWithConfig] = EitherT { - tryToLoadRorCore(newConfig) + tryToLoadRorCore(rorSettings) .map(_ .map { engine => EngineWithConfig( engine = engine, - config = newConfig, + config = rorSettings, expirationConfig = configExpiration.map(engineExpirationConfig) ) } @@ -275,8 +275,8 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def tryToLoadRorCore(config: RawRorSettings) = - boot.loadRorEngine(config, rorConfigurationIndex) + private def tryToLoadRorCore(rorSettings: RawRorSettings) = + boot.loadRorEngine(rorSettings, esConfig) private def replaceCurrentEngine(newEngineWithConfig: EngineWithConfig) (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala index 63b6d7f89d..1cacf24968 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala @@ -29,25 +29,25 @@ import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexCo import tech.beshu.ror.boot.RorInstance.RawConfigReloadError.{ConfigUpToDate, ReloadingFailed, RorInstanceStopped} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, initialEngine: (Engine, RawRorSettings), reloadInProgress: Semaphore[Task], - indexConfigManager: IndexSettingsManager[RawRorSettings], - rorConfigurationIndex: RorConfigurationIndex) + indexConfigManager: IndexSettingsManager[RawRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine( name = "main", boot = boot, + esConfig = esConfig, initialEngine = InitialEngine.Configured(engine = initialEngine._1, config = initialEngine._2, expirationConfig = None), - reloadInProgress = reloadInProgress, - rorConfigurationIndex = rorConfigurationIndex + reloadInProgress = reloadInProgress ) { def forceReloadAndSave(config: RawRorSettings) @@ -122,7 +122,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, private def saveConfig(newConfig: RawRorSettings): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { for { - saveResult <- indexConfigManager.save(newConfig, rorConfigurationIndex) + saveResult <- indexConfigManager.save(rorConfigurationIndex, newConfig) } yield saveResult.left.map(IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala index 12da1f4cd6..555924556d 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala @@ -22,7 +22,7 @@ import monix.eval.Task import monix.execution.Scheduler import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks -import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.{StartingFailure, TestEngine} import tech.beshu.ror.boot.RorInstance.* @@ -32,21 +32,19 @@ import tech.beshu.ror.boot.engines.ConfigHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.ExpirationConfig import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError -import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorConfigurationIndex: RorConfigurationIndex) + indexTestConfigManager: IndexSettingsManager[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) - extends BaseReloadableEngine( - "test", boot, initialEngine, reloadInProgress, rorConfigurationIndex - ) { + extends BaseReloadableEngine("test", boot, esConfig, initialEngine, reloadInProgress) { def currentTestConfig() (implicit requestId: RequestId): Task[TestConfig] = { @@ -184,7 +182,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, private def saveConfigInIndex[A](newConfig: TestRorSettings.Present, onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { - EitherT(indexTestConfigManager.save(newConfig, rorConfigurationIndex)) + EitherT(indexTestConfigManager.save(newConfig)) .leftMap(onFailure) } @@ -210,7 +208,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, private def loadRorConfigFromIndex(): EitherT[Task, IndexConfigReloadError, TestRorSettings] = EitherT { indexTestConfigManager - .load(rorConfigurationIndex) + .load() .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) } @@ -235,10 +233,10 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, object TestConfigBasedReloadableEngine { def create(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorConfigurationIndex: RorConfigurationIndex) + indexTestConfigManager: IndexSettingsManager[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler): TestConfigBasedReloadableEngine = { val engine = initialEngine match { @@ -249,7 +247,7 @@ object TestConfigBasedReloadableEngine { case TestEngine.Invalidated(config, expiration) => InitialEngine.Invalidated(config, expirationConfig(expiration)) } - new TestConfigBasedReloadableEngine(boot, engine, reloadInProgress, indexTestConfigManager, rorConfigurationIndex) + new TestConfigBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, indexTestConfigManager) } private def expirationConfig(config: TestEngine.Expiration) = EngineExpirationConfig(config.ttl, config.validTo) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala deleted file mode 100644 index a66033fb3e..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/Config.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.index - -// todo: what about it? -private[index] object Config { - object rorSettingsIndexConst { - val id = "1" - val settingsKey = "settings" - } - - object rorTestSettingsIndexConst { - val id = "2" - } -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala similarity index 70% rename from core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index e271f3ccce..541289917a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -19,6 +19,7 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexMainSettingsManager.Const import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.* @@ -28,18 +29,19 @@ import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -final class IndexJsonContentServiceBasedIndexSettingsManager(indexJsonContentService: IndexJsonContentService, - rarRorConfigYamlParser: RawRorSettingsYamlParser) +final class IndexJsonContentServiceBasedIndexMainSettingsManager(settingsIndex: RorConfigurationIndex, + indexJsonContentService: IndexJsonContentService, + rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[RawRorSettings] with Logging { - override def load(indexName: RorConfigurationIndex): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { + override def load(): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { indexJsonContentService - .sourceOf(indexName.index, Config.rorSettingsIndexConst.id) + .sourceOf(settingsIndex.index, Const.id) .flatMap { case Right(source) => source - .find(_._1 == Config.rorSettingsIndexConst.settingsKey) + .find(_._1 == Const.settingsKey) .map { case (_, rorYamlString) => rarRorConfigYamlParser .fromString(rorYamlString) @@ -53,15 +55,21 @@ final class IndexJsonContentServiceBasedIndexSettingsManager(indexJsonContentSer } } - override def save(settings: RawRorSettings, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] = { + override def save(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { indexJsonContentService .saveContent( - rorConfigurationIndex.index, - Config.rorSettingsIndexConst.id, - Map(Config.rorSettingsIndexConst.settingsKey -> settings.raw) + settingsIndex.index, + Const.id, + Map(Const.settingsKey -> settings.raw) ) .map { _.left.map { case CannotWriteToIndex => CannotSaveSettings } } } } +object IndexJsonContentServiceBasedIndexMainSettingsManager { + private [IndexJsonContentServiceBasedIndexMainSettingsManager] object Const { + val id = "1" + val settingsKey = "settings" + } +} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index 8bef0026b7..dbe3f358dc 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -51,16 +51,17 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -final class IndexJsonContentServiceBasedIndexTestSettingsManager(indexJsonContentService: IndexJsonContentService, +final class IndexJsonContentServiceBasedIndexTestSettingsManager(settingsIndex: RorConfigurationIndex, + indexJsonContentService: IndexJsonContentService, rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[TestRorSettings] with Logging { type Error = RorSettingsLoader.Error[LoadingIndexSettingsError] - override def load(indexName: RorConfigurationIndex): Task[Either[Error, TestRorSettings]] = { + override def load(): Task[Either[Error, TestRorSettings]] = { indexJsonContentService - .sourceOf(indexName.index, Config.rorTestSettingsIndexConst.id) + .sourceOf(settingsIndex.index, Const.id) .flatMap { case Right(source) => val properties = source.collect { case (key: String, value: String) => (key, value) } @@ -72,14 +73,9 @@ final class IndexJsonContentServiceBasedIndexTestSettingsManager(indexJsonConten } } - override def save(settings: TestRorSettings, - rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] = { + override def save(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { indexJsonContentService - .saveContent( - rorConfigurationIndex.index, - Config.rorTestSettingsIndexConst.id, - formatSettings(settings) - ) + .saveContent(settingsIndex.index, Const.id, formatSettings(settings)) .map { _.left.map { case CannotWriteToIndex => CannotSaveSettings } } @@ -246,7 +242,8 @@ final class IndexJsonContentServiceBasedIndexTestSettingsManager(indexJsonConten } private object IndexJsonContentServiceBasedIndexTestSettingsManager { - object Const { + private [IndexJsonContentServiceBasedIndexTestSettingsManager] object Const { + val id = "2" object properties { val settings = "settings" val expirationTtl = "expiration_ttl_millis" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala index e6f557baa8..48ceb76aec 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -18,17 +18,17 @@ package tech.beshu.ror.configuration.index import cats.Show import monix.eval.Task -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.loader.RorSettingsLoader import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError +// todo: maybe we need settings manager to encapsulate file and index loading/saving logic? // todo: it looks like this manager should extend RorConfigLoader trait IndexSettingsManager[SETTINGS] { - def load(indexName: RorConfigurationIndex): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] + def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] - def save(settings: SETTINGS, rorConfigurationIndex: RorConfigurationIndex): Task[Either[SavingIndexSettingsError, Unit]] + def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] // todo: is this ok? protected final def settingsLoaderError(error: LoadingIndexSettingsError): Task[Either[SpecializedError[LoadingIndexSettingsError], SETTINGS]] = diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala similarity index 53% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala index 04533efe8d..cee1798847 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala @@ -21,75 +21,49 @@ import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} +import tech.beshu.ror.configuration.RorProperties.LoadingAttemptsCount import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.LoadedRorConfig.IndexParsingError import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* -import scala.concurrent.duration.DurationInt +import java.nio.file.Path import scala.language.postfixOps -// todo: indexConfigManager should be passed in constructor? // todo: refactor methods -object LoadRawRorConfig extends Logging { +class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSettings]) + extends Logging { + + def loadFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + forceLoadFromFile(settings) + } def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackFileLoadingSettings: LoadFromFileSettings, - indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { - attemptLoadingConfigFromIndex( + fallbackFileLoadingSettings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + attemptLoadingFromIndex( settings = indexLoadingSettings, - fallback = loadRorConfigFromFile(fallbackFileLoadingSettings), - indexConfigManager + fallback = loadRorSettingsFromFile(fallbackFileLoadingSettings) ) } - def loadFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { - forceLoadRorConfigFromFile(settings) - } - - def loadFromIndex(settings: LoadFromIndexSettings, - indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { - for { - // todo: is the copy ok? - result <- loadRorConfigFromIndex( - settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)), - indexConfigManager - ) - rawRorConfig <- result match { - case Left(LoadedRorConfig.IndexNotExist) => - Task.now(Left(LoadedRorConfig.IndexNotExist: LoadedRorConfig.Error)) - case Left(LoadedRorConfig.IndexUnknownStructure) => - Task.now(Left(LoadedRorConfig.IndexUnknownStructure: LoadedRorConfig.Error)) - case Left(error@LoadedRorConfig.IndexParsingError(_)) => - Task.now(Left(error: LoadedRorConfig.Error)) - case Right(value) => - Task.now(Right(value)) - } - } yield rawRorConfig - } - - private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: Task[Either[LoadedRorConfig.Error, RawRorSettings]], - indexConfigManager: IndexSettingsManager[RawRorSettings]): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { + private def attemptLoadingFromIndex(settings: LoadFromIndexSettings, + fallback: Task[Either[RorMainSettingsManager.Error, RawRorSettings]]): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { settings.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => for { - result <- loadRorConfigFromIndex(settings, indexConfigManager) + result <- loadRorConfigFromIndex(settings) rawRorConfig <- result match { - case Left(LoadedRorConfig.IndexNotExist) => - attemptLoadingConfigFromIndex( + case Left(RorMainSettingsManager.IndexNotExist) => + attemptLoadingFromIndex( settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback, - indexConfigManager + fallback = fallback ) - case Left(LoadedRorConfig.IndexUnknownStructure) => - Task.now(Left(LoadedRorConfig.IndexUnknownStructure)) - case Left(error@LoadedRorConfig.IndexParsingError(_)) => + case Left(RorMainSettingsManager.IndexUnknownStructure) => + Task.now(Left(RorMainSettingsManager.IndexUnknownStructure)) + case Left(error@RorMainSettingsManager.IndexParsingError(_)) => Task.now(Left(error)) case Right(value) => Task.now(Right(value)) @@ -98,13 +72,12 @@ object LoadRawRorConfig extends Logging { } } - private def loadRorConfigFromIndex(settings: LoadFromIndexSettings, - indexConfigManager: IndexSettingsManager[RawRorSettings]) = { + private def loadRorConfigFromIndex(settings: LoadFromIndexSettings) = { val rorConfigIndex = settings.rorConfigIndex logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") EitherT { - indexConfigManager - .load(settings.rorConfigIndex) + indexSettingsManager + .load() .delayExecution(settings.loadingDelay.value.value) }.map { rawRorConfig => logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") @@ -118,11 +91,12 @@ object LoadRawRorConfig extends Logging { .value } - private def loadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { + // todo: these two are almost the same (logging differs only) + private def loadRorSettingsFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) .leftMap { error => val newError = convertFileError(error) logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") @@ -131,11 +105,11 @@ object LoadRawRorConfig extends Logging { .value } - private def forceLoadRorConfigFromFile(settings: LoadFromFileSettings): Task[Either[LoadedRorConfig.Error, RawRorSettings]] = { + private def forceLoadFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { val rorSettingsFile = settings.rorSettingsFile - val rawRorConfigYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") - EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorConfigYamlParser).load()) + EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) .leftMap { error => val newError = convertFileError(error) logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") @@ -144,31 +118,43 @@ object LoadRawRorConfig extends Logging { .value } - private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadedRorConfig.Error = { + private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): RorMainSettingsManager.Error = { error match { case ParsingError(error) => val show = error.show - LoadedRorConfig.FileParsingError(show) - case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadedRorConfig.FileNotExist(file.path) + RorMainSettingsManager.FileParsingError(show) + case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => RorMainSettingsManager.FileNotExist(file.path) } } private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]) = error match { - case ParsingError(error) => LoadedRorConfig.IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadedRorConfig.IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadedRorConfig.IndexUnknownStructure + case ParsingError(error) => RorMainSettingsManager.IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => RorMainSettingsManager.IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => RorMainSettingsManager.IndexUnknownStructure } - private def logIndexLoadingError[A](error: LoadedRorConfig.LoadingIndexError): Unit = { + private def logIndexLoadingError[A](error: RorMainSettingsManager.LoadingIndexError): Unit = { error match { - case IndexParsingError(message) => + case RorMainSettingsManager.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedRorConfig.IndexUnknownStructure => + case RorMainSettingsManager.IndexUnknownStructure => logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") - case LoadedRorConfig.IndexNotExist => + case RorMainSettingsManager.IndexNotExist => logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") } } } +object RorMainSettingsManager { + + // todo: do we need two hierarchies? + sealed trait Error + final case class FileParsingError(message: String) extends Error + final case class FileNotExist(path: Path) extends Error + + sealed trait LoadingIndexError extends Error + final case class IndexParsingError(message: String) extends Error with LoadingIndexError + case object IndexUnknownStructure extends Error with LoadingIndexError + case object IndexNotExist extends Error with LoadingIndexError +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala index cd5c238f14..1ad23551da 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala @@ -21,6 +21,7 @@ import monix.eval.Task import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError +// todo: do we need it? trait RorSettingsLoader[SPECIALIZED_ERROR] { def load(): Task[Either[RorSettingsLoader.Error[SPECIALIZED_ERROR], RawRorSettings]] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala similarity index 73% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala index 752e3d9f39..5e3d724e8f 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/LoadRawTestRorConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala @@ -24,48 +24,43 @@ import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, Loading import tech.beshu.ror.configuration.TestRorSettings import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.LoadedTestRorConfig.{IndexParsingError, LoadingIndexError} import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.RorTestSettingsLoader.{IndexNotExist, IndexParsingError, IndexUnknownStructure, LoadingIndexError} import tech.beshu.ror.implicits.* import scala.concurrent.duration.DurationInt import scala.language.postfixOps - -object LoadRawTestRorConfig extends Logging { +class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSettings]) + extends Logging { def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackConfig: TestRorSettings, - indexConfigManager: IndexSettingsManager[TestRorSettings]): Task[Either[LoadingIndexError, TestRorSettings]] = { + fallbackConfig: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, - fallback = fallbackConfig, - indexConfigManager + fallback = fallbackConfig ) } private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, - fallback: TestRorSettings, - indexConfigManager: IndexSettingsManager[TestRorSettings]): Task[Either[LoadingIndexError, TestRorSettings]] = { + fallback: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { settings.loadingAttemptsCount.value.value match { case 0 => Task.now(Right(fallback)) case attemptsCount => for { result <- loadTestRorConfigFromIndex( - settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)), - indexConfigManager + settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)) ) rawRorConfig <- result match { - case Left(LoadedTestRorConfig.IndexNotExist) => + case Left(IndexNotExist) => attemptLoadingConfigFromIndex( settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback, - indexConfigManager + fallback = fallback ) - case Left(error@LoadedTestRorConfig.IndexUnknownStructure) => + case Left(error@IndexUnknownStructure) => Task.now(Left(error)) - case Left(error@LoadedTestRorConfig.IndexParsingError(_)) => + case Left(error@IndexParsingError(_)) => Task.now(Left(error)) case Right(value) => Task.now(Right(value)) @@ -74,8 +69,7 @@ object LoadRawTestRorConfig extends Logging { } } - private def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings, - indexConfigManager: IndexSettingsManager[TestRorSettings]) = { + private def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings) = { val rorConfigIndex = settings.rorConfigIndex val loadingDelay = settings.loadingDelay logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") @@ -101,22 +95,29 @@ object LoadRawTestRorConfig extends Logging { .value } - private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadedTestRorConfig.LoadingIndexError = + private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingIndexError = error match { - case ParsingError(error) => LoadedTestRorConfig.IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadedTestRorConfig.IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadedTestRorConfig.IndexUnknownStructure + case ParsingError(error) => IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => IndexUnknownStructure } - private def logIndexLoadingError(error: LoadedTestRorConfig.LoadingIndexError): Unit = { + private def logIndexLoadingError(error: LoadingIndexError): Unit = { error match { case IndexParsingError(message) => logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadedTestRorConfig.IndexUnknownStructure => + case IndexUnknownStructure => logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") - case LoadedTestRorConfig.IndexNotExist => + case IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") } } } + +object RorTestSettingsLoader { + sealed trait LoadingIndexError + final case class IndexParsingError(message: String) extends LoadingIndexError + case object IndexUnknownStructure extends LoadingIndexError + case object IndexNotExist extends LoadingIndexError +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala deleted file mode 100644 index a6c8cbeab3..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/domain.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.configuration.loader - -import java.nio.file.Path - -// todo: move? -object LoadedRorConfig { - - sealed trait Error - final case class FileParsingError(message: String) extends LoadedRorConfig.Error - final case class FileNotExist(path: Path) extends LoadedRorConfig.Error - - sealed trait LoadingIndexError - final case class IndexParsingError(message: String) extends LoadedRorConfig.Error with LoadingIndexError - case object IndexUnknownStructure extends LoadedRorConfig.Error with LoadingIndexError - case object IndexNotExist extends LoadedRorConfig.Error with LoadingIndexError -} - -object LoadedTestRorConfig { - - sealed trait LoadingIndexError - final case class IndexParsingError(message: String) extends LoadingIndexError - case object IndexUnknownStructure extends LoadingIndexError - case object IndexNotExist extends LoadingIndexError -} diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala index 16ed02e98f..77823a2567 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction.* import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} -import tech.beshu.ror.configuration.loader.{LoadRawRorConfig, LoadedRorConfig} +import tech.beshu.ror.configuration.loader.{RorMainSettingsManager, LoadedRorConfig} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, unsafeNes} @@ -43,7 +43,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (ForceLoadRorConfigFromFile(esEnv.configPath), Right(ForcedFileConfig(rawRorConfig))), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromFile(esEnv.configPath) + val program = RorMainSettingsManager.loadFromFile(esEnv.configPath) val result = program.foldMap(compiler) val ffc = result.asInstanceOf[Right[Nothing, ForcedFileConfig[RawRorSettings]]] ffc.value.value shouldEqual rawRorConfig @@ -54,7 +54,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Right(IndexConfig(rorConfigurationIndex, rawRorConfig))), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromIndexWithFileFallback( + val program = RorMainSettingsManager.loadFromIndexWithFileFallback( configurationIndex = rorConfigurationIndex, loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(1), @@ -73,7 +73,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Right(IndexConfig(rorConfigurationIndex, rawRorConfig))), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromIndexWithFileFallback( + val program = RorMainSettingsManager.loadFromIndexWithFileFallback( configurationIndex = rorConfigurationIndex, loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), @@ -96,7 +96,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromFile(esEnv.configPath), Right(FileConfig(rawRorConfig))), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromIndexWithFileFallback( + val program = RorMainSettingsManager.loadFromIndexWithFileFallback( configurationIndex = rorConfigurationIndex, loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), @@ -112,7 +112,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexUnknownStructure)), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromIndexWithFileFallback( + val program = RorMainSettingsManager.loadFromIndexWithFileFallback( configurationIndex = rorConfigurationIndex, loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), @@ -128,7 +128,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexParsingError("error"))), ) val compiler = IdCompiler.instance(steps) - val program = LoadRawRorConfig.loadFromIndexWithFileFallback( + val program = RorMainSettingsManager.loadFromIndexWithFileFallback( configurationIndex = rorConfigurationIndex, loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), From b92a88e03314cd8f36a10ddf5af79d154538a65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 11 Jul 2025 09:47:58 +0200 Subject: [PATCH 013/103] refactoring --- azure-pipelines.yml | 2 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 5 +- .../tech/beshu/ror/boot/RorInstance.scala | 21 ++--- .../MainConfigBasedReloadableEngine.scala | 6 +- .../EsConfigBasedRorSettings.scala | 84 +++++++++++++------ .../ror/configuration/RorBootSettings.scala | 17 ++-- .../ror/configuration/SslConfiguration.scala | 49 +++++------ .../loader/RorTestSettingsLoader.scala | 3 +- .../main/scala/tech/beshu/ror/es/EsEnv.scala | 13 +-- .../tech/beshu/ror/utils/SSLCertHelper.scala | 9 +- .../LoadRawRorSettingsTest.scala | 16 ++-- .../beshu/ror/es/utils/EsEnvProvider.scala | 4 +- 12 files changed, 121 insertions(+), 108 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d03b1e2aa7..967b40d92b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -553,7 +553,6 @@ stages: fetchDepth: 1 clean: false persistCredentials: true - timeoutInMinutes: 180 - script: | set -e @@ -574,6 +573,7 @@ stages: echo "[RELEASE_ROR] executing ROR_TASK = $ROR_TASK" echo ">>> ($ROR_TASK) Releasing ROR" && ci/run-pipeline.sh + timeoutInMinutes: 360 env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index b0f2b01342..900684ae59 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -191,12 +191,11 @@ class ReadonlyRest(coreFactory: CoreFactory, EitherT.right[StartingFailure] { val rorSettingsFile = esConfig.loadingRorCoreStrategy.rorSettingsFile val rorSettingsMaxSize = esConfig.loadingRorCoreStrategy.rorSettingsMaxSize - val rorConfigIndex = esConfig.rorConfigIndex esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithoutPeriodicIndexCheck(this, esConfig, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize, rorConfigIndex) + RorInstance.createWithPeriodicIndexCheck(this, esConfig, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 0d48f9d2b5..ceb5619d34 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -28,15 +28,15 @@ import org.apache.logging.log4j.scala.Logging import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} -import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} import tech.beshu.ror.boot.engines.{Engines, MainConfigBasedReloadableEngine, TestConfigBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.loader.FileRorSettingsLoader +import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -52,7 +52,6 @@ class RorInstance private(boot: ReadonlyRest, testReloadInProgress: Semaphore[Task], indexConfigManager: IndexSettingsManager[RawRorSettings], indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorSettingsIndex: RorConfigurationIndex, // todo: do we need this? rorSettingsFile: File, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, @@ -281,11 +280,10 @@ object RorInstance { indexTestConfigManager: IndexSettingsManager[TestRorSettings], refreshInterval: RefreshInterval, rorSettingsFile: File, - rorSettingsMaxSize: Information, - rorSettingsIndex: RorConfigurationIndex) + rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) + create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, @@ -295,11 +293,10 @@ object RorInstance { indexConfigManager: IndexSettingsManager[RawRorSettings], indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorSettingsFile: File, - rorSettingsMaxSize: Information, - rorSettingsIndex: RorConfigurationIndex) + rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize, rorSettingsIndex) + create(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) } private def create(boot: ReadonlyRest, @@ -310,8 +307,7 @@ object RorInstance { indexConfigManager: IndexSettingsManager[RawRorSettings], indexTestConfigManager: IndexSettingsManager[TestRorSettings], rorSettingsFile: File, - rorSettingsMaxSize: Information, - rorSettingsIndex: RorConfigurationIndex) + rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { @@ -327,7 +323,6 @@ object RorInstance { testReloadInProgress = isTestReloadInProgressSemaphore, indexConfigManager = indexConfigManager, indexTestConfigManager = indexTestConfigManager, - rorSettingsIndex = rorSettingsIndex, rorSettingsFile = rorSettingsFile, rorSettingsMaxSize = rorSettingsMaxSize ) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala index 1cacf24968..80a2f14c3a 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala @@ -21,7 +21,7 @@ import monix.catnap.Semaphore import monix.eval.Task import monix.execution.Scheduler import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.{RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.boot.RorInstance.* @@ -122,13 +122,13 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, private def saveConfig(newConfig: RawRorSettings): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { for { - saveResult <- indexConfigManager.save(rorConfigurationIndex, newConfig) + saveResult <- indexConfigManager.save(newConfig) } yield saveResult.left.map(IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply) } private def loadRorConfigFromIndex() = { indexConfigManager - .load(rorConfigurationIndex) + .load() .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index cc7e795309..3ba2eeeeeb 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -30,6 +30,7 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrat import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.language.implicitConversions @@ -43,7 +44,7 @@ object EsConfigBasedRorSettings { def from(esEnv: EsEnv) (implicit systemContext: SystemContext): Task[Either[LoadEsConfigError, EsConfigBasedRorSettings]] = { - val configFile = esEnv.elasticsearchConfig + val configFile = esEnv.elasticsearchYmlFile val result = for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) bootSettings <- loadRorBootSettings(esEnv) @@ -62,23 +63,25 @@ object EsConfigBasedRorSettings { private def loadRorBootSettings(esEnv: EsEnv) (implicit systemContext: SystemContext) = { EitherT(RorBootSettings.load(esEnv)) - .leftMap(error => MalformedContent(esEnv.configPath, error.message)) + .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } private def loadXpackSettings(esEnv: EsEnv, ossDistribution: Boolean) (implicit systemContext: SystemContext) = { - EitherT.fromEither[Task] { - implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) - new YamlFileBasedSettingsLoader(esEnv.configPath) - .loadSettings[XpackSettings](settingsName = "X-Pack settings") - .left.map(error => MalformedContent(esEnv.configPath, error.message)) + EitherT { + Task.delay { + implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) + new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) + .loadSettings[XpackSettings](settingsName = "X-Pack settings") + .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) + } } } private def loadSslSettings(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, Option[RorSsl]] = { EitherT(RorSsl.load(esEnv, rorFileSettings)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig, error.message)) + .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) .subflatMap { case Some(ssl) if xpackSettings.securityEnabled => Left(RorSettingsInactiveWhenXpackSecurityIsEnabled) @@ -90,15 +93,16 @@ object EsConfigBasedRorSettings { private def loadLoadingRorCoreStrategyAndRorIndex(esEnv: EsEnv) (implicit systemContext: SystemContext) = { EitherT.fromEither[Task] { - import decoders.{loadRorCoreStrategyDecoder, rorConfigurationIndexDecoder} - val loader = new YamlFileBasedSettingsLoader(esEnv.configPath) + implicit val loadRorCoreStrategyDecoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) + import decoders.rorSettingsIndexDecoder + val loader = new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) for { strategy <- loader .loadSettings[LoadingRorCoreStrategy](settingsName = "ROR loading core settings") - .left.map(error => MalformedContent(esEnv.configPath, error.message)) + .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) rorIndex <- loader .loadSettings[RorConfigurationIndex](settingsName = "ROR configuration index settings") - .left.map(error => MalformedContent(esEnv.configPath, error.message)) + .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } yield (strategy, rorIndex) } } @@ -142,25 +146,30 @@ object EsConfigBasedRorSettings { } private object decoders { - implicit val loadRorCoreStrategyDecoder: Decoder[LoadingRorCoreStrategy] = { + implicit def loadRorCoreStrategyDecoder(esEnv: EsEnv) + (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategy] = { YamlKeyDecoder[Boolean]( - path = NonEmptyList.of("readonlyrest", "settings", "file", "force_load_from_file"), - alternativePath = NonEmptyList.of("readonlyrest", "force_load_from_file"), // for a sake of backward compatibility + path = NonEmptyList.of("readonlyrest", "force_load_from_file"), default = false - ) map { - case true => LoadingRorCoreStrategy.ForceLoadingFromFile(???) - case false => LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(???, ???) + ) flatMap { + case true => + loadFromFileSettingsDecoder(esEnv, systemContext.propertiesProvider) + .map(LoadingRorCoreStrategy.ForceLoadingFromFile.apply) + case false => + for { + loadFromIndexSettings <- loadFromIndexSettingsDecoder(systemContext.propertiesProvider) + loadFromFileSettings <- loadFromFileSettingsDecoder(esEnv, systemContext.propertiesProvider) + } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(loadFromIndexSettings, loadFromFileSettings) } } - implicit val rorConfigurationIndexDecoder: Decoder[RorConfigurationIndex] = { + implicit val rorSettingsIndexDecoder: Decoder[RorConfigurationIndex] = { implicit val indexNameDecoder: Decoder[RorConfigurationIndex] = Decoder[NonEmptyString] .map(IndexName.Full.apply) .map(RorConfigurationIndex.apply) YamlKeyDecoder[RorConfigurationIndex]( - path = NonEmptyList.of("readonlyrest", "settings", "in_index", "index_name"), - alternativePath = NonEmptyList.of("readonlyrest", "settings_index"), // for a sake of backward compatibility + path = NonEmptyList.of("readonlyrest", "settings_index"), default = RorConfigurationIndex.default ) } @@ -183,10 +192,35 @@ object EsConfigBasedRorSettings { } } - // private implicit val loadFromFileSettingsDecoder: Decoder[LoadFromFileSettings] = { - // //YamlKeyDecoder[String](path = NonEmptyList.of("readonlyrest", "settings", "file", "path")) - // ??? - // } + private implicit def loadFromFileSettingsDecoder(esEnv: EsEnv, + propertiesProvider: PropertiesProvider): Decoder[LoadFromFileSettings] = { + for { + settingsFile <- Decoder.instance(_ => Right( + RorProperties.rorSettingsCustomFile( propertiesProvider).getOrElse(esEnv.configDir / "readonlyrest.yml") + )) + settingsMaxSize <- Decoder.instance(_ => Right( + RorProperties.rorSettingsMaxSize(propertiesProvider) + )) + } yield LoadFromFileSettings(settingsFile, settingsMaxSize) + } + + private implicit def loadFromIndexSettingsDecoder(propertiesProvider: PropertiesProvider): Decoder[LoadFromIndexSettings] = { + for { + settingsIndex <- rorSettingsIndexDecoder + refreshInterval <- Decoder.instance(_ => Right(RorProperties.rorIndexSettingsReloadInterval(propertiesProvider))) + loadingAttemptsInterval <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(propertiesProvider))) + loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) + loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) + settingsMaxSize <- Decoder.instance(_ => Right(RorProperties.rorSettingsMaxSize(propertiesProvider))) + } yield LoadFromIndexSettings( + settingsIndex, + refreshInterval, + loadingAttemptsInterval, + loadingAttemptsCount, + loadingDelay, + settingsMaxSize + ) + } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala index 52d339799a..3ad7173c41 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala @@ -16,11 +16,9 @@ */ package tech.beshu.ror.configuration -import better.files.File import cats.data.NonEmptyList import io.circe.Decoder import monix.eval.Task -import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.EsEnv @@ -30,18 +28,13 @@ import tech.beshu.ror.utils.yaml.YamlKeyDecoder final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, rorFailedToStartResponse: RorFailedToStartResponse) -object RorBootSettings extends Logging { +object RorBootSettings { def load(env: EsEnv) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootSettings]] = Task { - implicit val rorBootConfigurationDecoder: Decoder[RorBootSettings] = Decoders.decoder - loadRorBootstrapSettings(env.elasticsearchConfig) - } - - private def loadRorBootstrapSettings(configFile: File) - (implicit decoder: Decoder[RorBootSettings], - systemContext: SystemContext) = { - new YamlFileBasedSettingsLoader(configFile).loadSettings[RorBootSettings](settingsName = "ROR boot settings") + implicit val rorBootSettingsDecoder: Decoder[RorBootSettings] = Decoders.decoder + new YamlFileBasedSettingsLoader(env.elasticsearchYmlFile) + .loadSettings[RorBootSettings](settingsName = "ROR boot settings") } final case class RorNotStartedResponse(httpCode: RorNotStartedResponse.HttpCode) @@ -63,7 +56,7 @@ object RorBootSettings extends Logging { } } -private object Decoders extends Logging { +private object Decoders { object consts { val rorSection = "readonlyrest" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 0b574ecf52..5b3a57d4d6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -28,9 +28,6 @@ import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.SSLCertHelper -import java.io.File as JFile -import java.nio.file.{Path, Paths} - sealed trait RorSsl object RorSsl extends Logging { @@ -62,8 +59,8 @@ object RorSsl extends Logging { def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSsl]]] = Task { - implicit val sslDecoder: Decoder[Option[RorSsl]] = SslDecoders.rorSslDecoder(esEnv.configPath) - val esConfigFile = esEnv.elasticsearchConfig + implicit val sslDecoder: Decoder[Option[RorSsl]] = SslDecoders.rorSslDecoder(esEnv.configDir) + val esConfigFile = esEnv.elasticsearchYmlFile loadSslConfigFromFile(esConfigFile) .fold( error => Left(error), @@ -114,12 +111,12 @@ sealed trait SslConfiguration { object SslConfiguration { final case class KeystorePassword(value: String) - final case class KeystoreFile(value: JFile) + final case class KeystoreFile(value: File) final case class TruststorePassword(value: String) - final case class TruststoreFile(value: JFile) - final case class ServerCertificateKeyFile(value: JFile) - final case class ServerCertificateFile(value: JFile) - final case class ClientTrustedCertificateFile(value: JFile) + final case class TruststoreFile(value: File) + final case class ServerCertificateKeyFile(value: File) + final case class ServerCertificateFile(value: File) + final case class ClientTrustedCertificateFile(value: File) final case class KeyPass(value: String) final case class KeyAlias(value: String) final case class Cipher(value: String) @@ -211,10 +208,10 @@ private object SslDecoders extends Logging { private implicit val cipherDecoder: Decoder[Cipher] = DecoderHelpers.decodeStringLike.map(Cipher.apply) private implicit val protocolDecoder: Decoder[Protocol] = DecoderHelpers.decodeStringLike.map(Protocol.apply) - private def clientCertificateConfigurationDecoder(basePath: Path): Decoder[Option[ClientCertificateConfiguration]] = { - val jFileDecoder: Decoder[JFile] = fileDecoder(basePath) - implicit val truststoreFileDecoder = jFileDecoder.map(TruststoreFile.apply) - implicit val clientTrustedCertificateFileDecoder = jFileDecoder.map(ClientTrustedCertificateFile.apply) + private def clientCertificateConfigurationDecoder(basePath: File): Decoder[Option[ClientCertificateConfiguration]] = { + val aFileDecoder: Decoder[File] = fileDecoder(basePath) + implicit val truststoreFileDecoder = aFileDecoder.map(TruststoreFile.apply) + implicit val clientTrustedCertificateFileDecoder = aFileDecoder.map(ClientTrustedCertificateFile.apply) val truststoreBasedClientCertificateConfigurationDecoder: Decoder[ClientCertificateConfiguration] = Decoder.forProduct2(consts.truststoreFile, consts.truststorePass)(ClientCertificateConfiguration.TruststoreBasedConfiguration.apply) @@ -246,11 +243,11 @@ private object SslDecoders extends Logging { } } - private def serverCertificateConfigurationDecoder(basePath: Path): Decoder[ServerCertificateConfiguration] = { - val jFileDecoder: Decoder[JFile] = fileDecoder(basePath) - implicit val keystoreFileDecoder = jFileDecoder.map(KeystoreFile.apply) - implicit val serverCertificateFileDecoder = jFileDecoder.map(ServerCertificateFile.apply) - implicit val serverCertificateKeyFileDecoder = jFileDecoder.map(ServerCertificateKeyFile.apply) + private def serverCertificateConfigurationDecoder(basePath: File): Decoder[ServerCertificateConfiguration] = { + val aFileDecoder: Decoder[File] = fileDecoder(basePath) + implicit val keystoreFileDecoder = aFileDecoder.map(KeystoreFile.apply) + implicit val serverCertificateFileDecoder = aFileDecoder.map(ServerCertificateFile.apply) + implicit val serverCertificateKeyFileDecoder = aFileDecoder.map(ServerCertificateKeyFile.apply) val keystoreBasedServerCertificateConfigurationDecoder: Decoder[ServerCertificateConfiguration] = Decoder.forProduct4(consts.keystoreFile, consts.keystorePass, consts.keyAlias, consts.keyPass)(ServerCertificateConfiguration.KeystoreBasedConfiguration.apply) val fileBasedServerCertificateConfigurationDecoder: Decoder[ServerCertificateConfiguration] = @@ -281,7 +278,7 @@ private object SslDecoders extends Logging { } } - def rorSslDecoder(basePath: Path): Decoder[Option[RorSsl]] = Decoder.instance { c => + def rorSslDecoder(basePath: File): Decoder[Option[RorSsl]] = Decoder.instance { c => implicit val isFipsCompliantDecoder: Decoder[FipsMode] = Decoder.decodeString.emap { case "NON_FIPS" => Right(FipsMode.NonFips) case "SSL_ONLY" => Right(FipsMode.SslOnly) @@ -307,7 +304,7 @@ private object SslDecoders extends Logging { } } - private def sslInternodeConfigurationDecoder(basePath: Path, + private def sslInternodeConfigurationDecoder(basePath: File, fipsMode: FipsMode): Decoder[Option[InternodeSslConfiguration]] = Decoder.instance { c => whenEnabled(c) { for { @@ -329,7 +326,7 @@ private object SslDecoders extends Logging { } } - private def sslExternalConfigurationDecoder(basePath: Path, + private def sslExternalConfigurationDecoder(basePath: File, fipsMode: FipsMode): Decoder[Option[ExternalSslConfiguration]] = Decoder.instance { c => whenEnabled(c) { for { @@ -347,7 +344,7 @@ private object SslDecoders extends Logging { } } - private def sslCommonPropertiesDecoder(basePath: Path, c: HCursor) = { + private def sslCommonPropertiesDecoder(basePath: File, c: HCursor) = { for { ciphers <- c.downField(consts.allowedCiphers).as[Option[Set[Cipher]]] protocols <- c.downField(consts.allowedProtocols).as[Option[Set[Protocol]]] @@ -371,8 +368,6 @@ private object SslDecoders extends Logging { } yield result } - private def fileDecoder(basePath: Path): Decoder[JFile] = - Decoder - .decodeString - .map { str => basePath.resolve(Paths.get(str)).toFile } + private def fileDecoder(basePath: File): Decoder[File] = + Decoder.decodeString.map { str => basePath / str } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala index 5e3d724e8f..b0bf092760 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala @@ -72,10 +72,11 @@ class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSett private def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings) = { val rorConfigIndex = settings.rorConfigIndex val loadingDelay = settings.loadingDelay + // todo: log is ok? logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") EitherT { indexConfigManager - .load(rorConfigIndex) + .load() .delayExecution(loadingDelay.value.value) } .map { testConfig => diff --git a/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala b/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala index a17f16a016..6298c9216a 100644 --- a/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala +++ b/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala @@ -16,23 +16,18 @@ */ package tech.beshu.ror.es -import better.files.File - -import java.nio.file.Path +import better.files._ import scala.util.Try -final case class EsEnv(configPath: Path, modulesPath: Path, esVersion: EsVersion) { +final case class EsEnv(configDir: File, modulesDir: File, esVersion: EsVersion) { def isOssDistribution: Boolean = { Try { - !modulesPath.resolve("x-pack-security").toFile.exists() + !(modulesDir / "x-pack-security").exists } getOrElse { false } } - def elasticsearchConfig: File = { - File(s"${configPath.toAbsolutePath}/elasticsearch.yml") - } - + def elasticsearchYmlFile: File = configDir / "elasticsearch.yml" } diff --git a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala index 9abf13d1a7..3538710b7f 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.utils +import better.files.* import cats.effect.{IO, Resource} import io.netty.buffer.ByteBufAllocator import io.netty.channel.ChannelHandlerContext @@ -32,7 +33,7 @@ import tech.beshu.ror.configuration.SslConfiguration.ClientCertificateConfigurat import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.KeystoreBasedConfiguration import tech.beshu.ror.implicits.* -import java.io.{File, FileInputStream, FileReader, IOException} +import java.io.{FileInputStream, FileReader, IOException} import java.security.cert.{CertificateFactory, X509Certificate} import java.security.{KeyStore, PrivateKey} import javax.net.ssl.{KeyManagerFactory, SNIServerName, SSLEngine, TrustManagerFactory} @@ -201,7 +202,7 @@ object SSLCertHelper extends Logging { private def loadKeystoreFromFile(keystoreFile: File, password: Array[Char], fipsCompliant: Boolean): IO[KeyStore] = { Resource - .fromAutoCloseable(IO(new FileInputStream(keystoreFile))) + .fromAutoCloseable(IO(new FileInputStream(keystoreFile.toJava))) .use { keystoreFile => IO { val keystore = if (fipsCompliant) { @@ -270,7 +271,7 @@ object SSLCertHelper extends Logging { private def loadPrivateKey(file: File): IO[PrivateKey] = { Resource - .fromAutoCloseable(IO(new FileReader(file))) + .fromAutoCloseable(IO(new FileReader(file.toJava))) .use { privateKeyFileReader => IO { val pemParser = new PEMParser(privateKeyFileReader) @@ -283,7 +284,7 @@ object SSLCertHelper extends Logging { private def loadCertificateChain(file: File): IO[Array[X509Certificate]] = { Resource - .fromAutoCloseable(IO(new FileInputStream(file))) + .fromAutoCloseable(IO(new FileInputStream(file.toJava))) .use { certificateChainFile => IO { val certFactory = CertificateFactory.getInstance("X.509") diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala index 77823a2567..09b96fb579 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala @@ -40,10 +40,10 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ "Free monad loader program" should { "load forced file" in { val steps = List( - (ForceLoadRorConfigFromFile(esEnv.configPath), Right(ForcedFileConfig(rawRorConfig))), + (ForceLoadRorConfigFromFile(esEnv.configDir), Right(ForcedFileConfig(rawRorConfig))), ) val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromFile(esEnv.configPath) + val program = RorMainSettingsManager.loadFromFile(esEnv.configDir) val result = program.foldMap(compiler) val ffc = result.asInstanceOf[Right[Nothing, ForcedFileConfig[RawRorSettings]]] ffc.value.value shouldEqual rawRorConfig @@ -59,7 +59,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(1), loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configPath + fallbackConfigFilePath = esEnv.configDir ) val result = program.foldMap(compiler) val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] @@ -78,7 +78,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), loadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfigFilePath = esEnv.configPath + fallbackConfigFilePath = esEnv.configDir ) val result = program.foldMap(compiler) val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] @@ -93,7 +93,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromFile(esEnv.configPath), Right(FileConfig(rawRorConfig))), + (LoadRorConfigFromFile(esEnv.configDir), Right(FileConfig(rawRorConfig))), ) val compiler = IdCompiler.instance(steps) val program = RorMainSettingsManager.loadFromIndexWithFileFallback( @@ -101,7 +101,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), loadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfigFilePath = esEnv.configPath + fallbackConfigFilePath = esEnv.configDir ) val result = program.foldMap(compiler) result.toOption.get shouldBe FileConfig(rawRorConfig) @@ -117,7 +117,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configPath + fallbackConfigFilePath = esEnv.configDir ) val result = program.foldMap(compiler) result shouldBe a[Left[LoadedRorConfig.IndexUnknownStructure.type, _]] @@ -133,7 +133,7 @@ class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ loadingDelay = loadingDelay, loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configPath + fallbackConfigFilePath = esEnv.configDir ) val result = program.foldMap(compiler) result shouldBe a[Left[LoadedRorConfig.IndexParsingError, _]] diff --git a/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index d4b158ef42..f5192548d3 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -23,8 +23,8 @@ import tech.beshu.ror.es.{EsEnv, EsVersion} object EsEnvProvider { def create(environment: Environment): EsEnv = { EsEnv( - configPath = environment.configDir(), - modulesPath = environment.modulesDir(), + configDir = environment.configDir(), + modulesDir = environment.modulesDir(), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision) ) } From 55a31f7dbc01e2200494bc89200841e542766b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 11 Jul 2025 12:27:06 +0200 Subject: [PATCH 014/103] refactoring --- .../blocks/rules/kibana/BaseKibanaRule.scala | 2 +- .../rules/kibana/KibanaAccessRule.scala | 2 +- .../rules/kibana/KibanaUserDataRule.scala | 2 +- .../ror/accesscontrol/domain/indices.scala | 7 +- .../accesscontrol/factory/CoreFactory.scala | 8 +- .../factory/GlobalSettings.scala | 4 +- .../GlobalStaticSettingsDecoder.scala | 4 +- .../rules/kibana/KibanaRulesDecoders.scala | 4 +- .../kibana/KibanaUserDataRuleDecoder.scala | 2 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 9 -- .../SecurityProviderConfiguratorForFips.scala | 10 +- .../EsConfigBasedRorSettings.scala | 96 +++++++-------- .../ror/configuration/SslConfiguration.scala | 112 +++++++++--------- ...ServiceBasedIndexMainSettingsManager.scala | 4 +- ...ServiceBasedIndexTestSettingsManager.scala | 4 +- .../loader/RorMainSettingsManager.scala | 74 ++++++------ .../loader/RorTestSettingsLoader.scala | 10 +- .../BaseYamlLoadedAccessControlTest.scala | 4 +- .../acl/EnabledAccessControlListTests.scala | 2 +- .../user/UserDefinitionsValidatorTests.scala | 2 +- .../rules/kibana/KibanaAccessRuleTests.scala | 2 +- .../kibana/KibanaUserDataRuleTests.scala | 10 +- .../unit/acl/factory/AuditSettingsTests.scala | 20 ++-- .../unit/acl/factory/CoreFactoryTests.scala | 4 +- .../factory/ImpersonationWarningsTests.scala | 4 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 4 +- .../definitions/GlobalSettingsTests.scala | 4 +- .../ImpersonationSettingsTests.scala | 4 +- .../rules/BaseRuleSettingsDecoderTest.scala | 6 +- .../rules/auth/UsersRuleSettingsTests.scala | 4 +- .../KibanaAccessRuleSettingsTests.scala | 14 +-- .../KibanaUserDataRuleSettingsTests.scala | 40 +++---- .../LoadRawRorSettingsTest.scala | 4 +- .../configuration/SslConfigurationTest.scala | 46 +++---- .../configuration/loader/SummaryTest.scala | 4 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 4 +- .../SSLNetty4InternodeServerTransport.scala | 4 +- 38 files changed, 267 insertions(+), 275 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala index 9a424697d6..e28d22a4f7 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/BaseKibanaRule.scala @@ -253,7 +253,7 @@ abstract class BaseKibanaRule(val settings: Settings) object BaseKibanaRule { abstract class Settings(val access: KibanaAccess, - val rorIndex: RorConfigurationIndex) + val rorIndex: RorSettingsIndex) type ProcessingContext = ReaderT[Id, (RequestContext, KibanaIndexName), Boolean] object ProcessingContext { diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala index d0e695a1eb..886f494adf 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaAccessRule.scala @@ -60,6 +60,6 @@ object KibanaAccessRule { } final case class Settings(override val access: KibanaAccess, - override val rorIndex: RorConfigurationIndex) + override val rorIndex: RorSettingsIndex) extends BaseKibanaRule.Settings(access, rorIndex) } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaUserDataRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaUserDataRule.scala index 676a129833..2dd0c51a06 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaUserDataRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/kibana/KibanaUserDataRule.scala @@ -133,6 +133,6 @@ object KibanaUserDataRule { appsToHide: Set[KibanaApp], allowedApiPaths: Set[KibanaAllowedApiPath], metadata: Option[ResolvableJsonRepresentation], - override val rorIndex: RorConfigurationIndex) + override val rorIndex: RorSettingsIndex) extends BaseKibanaRule.Settings(access, rorIndex) } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala index 4c9cff4c1a..78ce8220d9 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala @@ -526,10 +526,9 @@ object IndexAttribute { case object Closed extends IndexAttribute } -// todo: change name to RorSettingsIndex -final case class RorConfigurationIndex(index: IndexName.Full) extends AnyVal { +final case class RorSettingsIndex(index: IndexName.Full) extends AnyVal { def toLocal: ClusterIndexName.Local = ClusterIndexName.Local(index) } -object RorConfigurationIndex { - val default: RorConfigurationIndex = RorConfigurationIndex(IndexName.Full(nes(".readonlyrest"))) +object RorSettingsIndex { + val default: RorSettingsIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))) } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index 37a271e30a..6baec1aa09 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -63,7 +63,7 @@ final case class Core(accessControl: AccessControlList, trait CoreFactory { def createCoreFrom(rorSettings: RawRorSettings, - rorSettingsIndex: RorConfigurationIndex, + rorSettingsIndex: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] @@ -74,7 +74,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) extends CoreFactory with Logging { override def createCoreFrom(rorSettings: RawRorSettings, - rorSettingsIndex: RorConfigurationIndex, + rorSettingsIndex: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] = { @@ -98,7 +98,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) } private def createCoreFromRorSection(rorSection: Json, - rorIndexNameConfiguration: RorConfigurationIndex, + rorIndexNameConfiguration: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { @@ -120,7 +120,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) } private def createFrom(settingsJson: Json, - rorConfigurationIndex: RorConfigurationIndex, + rorConfigurationIndex: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala index 1ee9da08ff..de89ed7c7b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.accesscontrol.factory -import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex} final case class GlobalSettings(showBasicAuthPrompt: Boolean, forbiddenRequestMessage: String, flsEngine: GlobalSettings.FlsEngine, - configurationIndex: RorConfigurationIndex, + configurationIndex: RorSettingsIndex, userIdCaseSensitivity: CaseSensitivity, usersDefinitionDuplicateUsernamesValidationEnabled: Boolean) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala index a360b06499..f0fe5ec830 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala @@ -17,7 +17,7 @@ package tech.beshu.ror.accesscontrol.factory.decoders import io.circe.Decoder -import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError @@ -29,7 +29,7 @@ object GlobalStaticSettingsDecoder { private val globalSettingsSectionName = "global_settings" - def instance(rorConfigurationIndex: RorConfigurationIndex): Decoder[GlobalSettings] = { + def instance(rorConfigurationIndex: RorSettingsIndex): Decoder[GlobalSettings] = { for { showBasicAuthPrompt <- decoderFor[Boolean]("prompt_for_basic_auth") forbiddenRequestMessage <- decoderFor[String]("response_if_req_forbidden") diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala index 9c8b3fccdd..1df17f2f65 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala @@ -22,7 +22,7 @@ import tech.beshu.ror.accesscontrol.blocks.Block.RuleDefinition import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaHideAppsRule.Settings import tech.beshu.ror.accesscontrol.blocks.rules.kibana.{KibanaAccessRule, KibanaHideAppsRule, KibanaIndexRule, KibanaTemplateIndexRule} import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeResolvableVariableCreator, RuntimeSingleResolvableVariable} -import tech.beshu.ror.accesscontrol.domain.{KibanaAccess, KibanaApp, KibanaIndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{KibanaAccess, KibanaApp, KibanaIndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.utils.CirceOps.* @@ -66,7 +66,7 @@ class KibanaTemplateIndexRuleDecoder(variableCreator: RuntimeResolvableVariableC } } -class KibanaAccessRuleDecoder(rorIndexNameConfiguration: RorConfigurationIndex) +class KibanaAccessRuleDecoder(rorIndexNameConfiguration: RorSettingsIndex) extends RuleBaseDecoderWithoutAssociatedFields[KibanaAccessRule] { override protected def decoder: Decoder[RuleDefinition[KibanaAccessRule]] = { diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala index 278aaf1af9..9774214adc 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala @@ -39,7 +39,7 @@ import tech.beshu.ror.utils.js.JsCompiler import scala.util.{Failure, Success} -class KibanaUserDataRuleDecoder(configurationIndex: RorConfigurationIndex, +class KibanaUserDataRuleDecoder(configurationIndex: RorSettingsIndex, variableCreator: RuntimeResolvableVariableCreator) (implicit jsCompiler: JsCompiler) extends RuleBaseDecoderWithoutAssociatedFields[KibanaUserDataRule] diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 900684ae59..7ba56efad3 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -75,10 +75,6 @@ class ReadonlyRest(coreFactory: CoreFactory, EitherT(rorSettingsLoader.loadFromFile(settings)) .leftMap(toStartingFailure) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => - // todo: move - // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) - // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) - // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) EitherT(rorSettingsLoader.loadFromIndexWithFileFallback(settings, fallbackSettings)) .leftMap(toStartingFailure) } @@ -90,11 +86,6 @@ class ReadonlyRest(coreFactory: CoreFactory, case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - // todo: move - // val loadingDelay = RorProperties.atStartupRorIndexSettingLoadingDelay(systemContext.propertiesProvider) - // val loadingAttemptsCount = RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(systemContext.propertiesProvider) - // val loadingAttemptsInterval = RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(systemContext.propertiesProvider) - EitherT { rorSettingsLoader.loadFromIndexWithFallback( indexLoadingSettings = settings, diff --git a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala index 56b6220d01..6d93347780 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala @@ -18,7 +18,7 @@ package tech.beshu.ror.boot import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider -import tech.beshu.ror.configuration.RorSsl +import tech.beshu.ror.configuration.RorSslSettings import tech.beshu.ror.configuration.SslConfiguration.FipsMode.{NonFips, SslOnly} import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -26,11 +26,11 @@ import java.security.Security object SecurityProviderConfiguratorForFips { - def configureIfRequired(ssl: RorSsl): Unit = { + def configureIfRequired(ssl: RorSslSettings): Unit = { val fipsModes = ssl match { - case RorSsl.OnlyExternalSslConfiguration(ssl) => ssl.fipsMode :: Nil - case RorSsl.OnlyInternodeSslConfiguration(ssl) => ssl.fipsMode :: Nil - case RorSsl.ExternalAndInternodeSslConfiguration(external, internode) => external.fipsMode :: internode.fipsMode :: Nil + case RorSslSettings.OnlyExternalSslSettings(ssl) => ssl.fipsMode :: Nil + case RorSslSettings.OnlyInternodeSslSettings(ssl) => ssl.fipsMode :: Nil + case RorSslSettings.ExternalAndInternodeSslSettings(external, internode) => external.fipsMode :: internode.fipsMode :: Nil } fipsModes .find { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index 3ba2eeeeeb..565a393e88 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -23,7 +23,7 @@ import io.circe.Decoder import monix.eval.Task import squants.information.Information import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy @@ -36,8 +36,8 @@ import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.language.implicitConversions final case class EsConfigBasedRorSettings(boot: RorBootSettings, - ssl: Option[RorSsl], - rorConfigIndex: RorConfigurationIndex, + ssl: Option[RorSslSettings], + rorConfigIndex: RorSettingsIndex, loadingRorCoreStrategy: LoadingRorCoreStrategy) object EsConfigBasedRorSettings { @@ -50,12 +50,12 @@ object EsConfigBasedRorSettings { bootSettings <- loadRorBootSettings(esEnv) loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex - xpackSettings <- loadXpackSettings(esEnv, esEnv.isOssDistribution) + xpackSettings <- loadXpackSecuritySettings(esEnv, esEnv.isOssDistribution) rorFileSettings = loadingRorCoreStrategy match { case ForceLoadingFromFile(settings) => settings case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings } - sslSettings <- loadSslSettings(esEnv, rorFileSettings, xpackSettings) + sslSettings <- loadRorSslSettings(esEnv, rorFileSettings, xpackSettings) } yield EsConfigBasedRorSettings(bootSettings, sslSettings, rorIndex, loadingRorCoreStrategy) result.value } @@ -66,24 +66,26 @@ object EsConfigBasedRorSettings { .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } - private def loadXpackSettings(esEnv: EsEnv, ossDistribution: Boolean) - (implicit systemContext: SystemContext) = { + private def loadXpackSecuritySettings(esEnv: EsEnv, ossDistribution: Boolean) + (implicit systemContext: SystemContext) = { EitherT { Task.delay { - implicit val xpackSettingsDecoder: Decoder[XpackSettings] = decoders.xpackSettingsDecoder(ossDistribution) + implicit val xpackSettingsDecoder: Decoder[XpackSecurity] = decoders.xpackSettingsDecoder(ossDistribution) new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) - .loadSettings[XpackSettings](settingsName = "X-Pack settings") + .loadSettings[XpackSecurity](settingsName = "X-Pack settings") .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } } } - private def loadSslSettings(esEnv: EsEnv, rorFileSettings: LoadFromFileSettings, xpackSettings: XpackSettings) - (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, Option[RorSsl]] = { - EitherT(RorSsl.load(esEnv, rorFileSettings)) + private def loadRorSslSettings(esEnv: EsEnv, + rorSettingsFromFileParameters: LoadFromFileParameters, + xpackSecurity: XpackSecurity) + (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, Option[RorSslSettings]] = { + EitherT(RorSslSettings.load(esEnv, rorSettingsFromFileParameters)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) .subflatMap { - case Some(ssl) if xpackSettings.securityEnabled => + case Some(ssl) if xpackSecurity.enabled => Left(RorSettingsInactiveWhenXpackSecurityIsEnabled) case rorSsl@(Some(_) | None) => Right(rorSsl) @@ -101,7 +103,7 @@ object EsConfigBasedRorSettings { .loadSettings[LoadingRorCoreStrategy](settingsName = "ROR loading core settings") .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) rorIndex <- loader - .loadSettings[RorConfigurationIndex](settingsName = "ROR configuration index settings") + .loadSettings[RorSettingsIndex](settingsName = "ROR configuration index settings") .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } yield (strategy, rorIndex) } @@ -109,34 +111,34 @@ object EsConfigBasedRorSettings { sealed trait LoadingRorCoreStrategy object LoadingRorCoreStrategy { - final case class ForceLoadingFromFile(settings: LoadFromFileSettings) extends LoadingRorCoreStrategy - final case class LoadFromIndexWithFileFallback(settings: LoadFromIndexSettings, - fallbackSettings: LoadFromFileSettings) + final case class ForceLoadingFromFile(parameters: LoadFromFileParameters) extends LoadingRorCoreStrategy + final case class LoadFromIndexWithFileFallback(parameters: LoadFromIndexParameters, + fallbackParameters: LoadFromFileParameters) extends LoadingRorCoreStrategy } - implicit class FromLoadingRorCoreStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { + implicit class ExtractFromLoadingRorSettingsStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { def rorSettingsFile: File = strategy match { - case ForceLoadingFromFile(settings) => settings.rorSettingsFile - case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings.rorSettingsFile + case ForceLoadingFromFile(parameters) => parameters.rorSettingsFile + case LoadFromIndexWithFileFallback(_, fallbackParameters) => fallbackParameters.rorSettingsFile } def rorSettingsMaxSize: Information = strategy match { - case ForceLoadingFromFile(settings) => settings.settingsMaxSize - case LoadFromIndexWithFileFallback(settings, _) => settings.settingsMaxSize + case ForceLoadingFromFile(parameters) => parameters.settingsMaxSize + case LoadFromIndexWithFileFallback(parameters, _) => parameters.settingsMaxSize } } - final case class LoadFromFileSettings(rorSettingsFile: File, - settingsMaxSize: Information) - final case class LoadFromIndexSettings(rorConfigIndex: RorConfigurationIndex, - refreshInterval: RefreshInterval, - loadingAttemptsInterval: LoadingAttemptsInterval, - loadingAttemptsCount: LoadingAttemptsCount, - loadingDelay: LoadingDelay, - settingsMaxSize: Information) + final case class LoadFromFileParameters(rorSettingsFile: File, + settingsMaxSize: Information) + final case class LoadFromIndexParameters(rorSettingsIndex: RorSettingsIndex, + refreshInterval: RefreshInterval, + loadingAttemptsInterval: LoadingAttemptsInterval, + loadingAttemptsCount: LoadingAttemptsCount, + loadingDelay: LoadingDelay, + settingsMaxSize: Information) - private final case class XpackSettings(securityEnabled: Boolean) + private final case class XpackSecurity(enabled: Boolean) sealed trait LoadEsConfigError object LoadEsConfigError { @@ -153,30 +155,30 @@ object EsConfigBasedRorSettings { default = false ) flatMap { case true => - loadFromFileSettingsDecoder(esEnv, systemContext.propertiesProvider) + loadFromFileParametersDecoder(esEnv, systemContext.propertiesProvider) .map(LoadingRorCoreStrategy.ForceLoadingFromFile.apply) case false => for { loadFromIndexSettings <- loadFromIndexSettingsDecoder(systemContext.propertiesProvider) - loadFromFileSettings <- loadFromFileSettingsDecoder(esEnv, systemContext.propertiesProvider) + loadFromFileSettings <- loadFromFileParametersDecoder(esEnv, systemContext.propertiesProvider) } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(loadFromIndexSettings, loadFromFileSettings) } } - implicit val rorSettingsIndexDecoder: Decoder[RorConfigurationIndex] = { - implicit val indexNameDecoder: Decoder[RorConfigurationIndex] = + implicit val rorSettingsIndexDecoder: Decoder[RorSettingsIndex] = { + implicit val indexNameDecoder: Decoder[RorSettingsIndex] = Decoder[NonEmptyString] .map(IndexName.Full.apply) - .map(RorConfigurationIndex.apply) - YamlKeyDecoder[RorConfigurationIndex]( + .map(RorSettingsIndex.apply) + YamlKeyDecoder[RorSettingsIndex]( path = NonEmptyList.of("readonlyrest", "settings_index"), - default = RorConfigurationIndex.default + default = RorSettingsIndex.default ) } - def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSettings] = { + def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecurity] = { if (isOssDistribution) { - Decoder.const(XpackSettings(securityEnabled = false)) + Decoder.const(XpackSecurity(enabled = false)) } else { val booleanDecoder = YamlKeyDecoder[Boolean]( path = NonEmptyList.of("xpack", "security", "enabled"), @@ -188,23 +190,23 @@ object EsConfigBasedRorSettings { ) map { _.toBoolean } - (booleanDecoder or stringDecoder) map XpackSettings.apply + (booleanDecoder or stringDecoder) map XpackSecurity.apply } } - private implicit def loadFromFileSettingsDecoder(esEnv: EsEnv, - propertiesProvider: PropertiesProvider): Decoder[LoadFromFileSettings] = { + private implicit def loadFromFileParametersDecoder(esEnv: EsEnv, + propertiesProvider: PropertiesProvider): Decoder[LoadFromFileParameters] = { for { settingsFile <- Decoder.instance(_ => Right( - RorProperties.rorSettingsCustomFile( propertiesProvider).getOrElse(esEnv.configDir / "readonlyrest.yml") + RorProperties.rorSettingsCustomFile(propertiesProvider).getOrElse(esEnv.configDir / "readonlyrest.yml") )) settingsMaxSize <- Decoder.instance(_ => Right( RorProperties.rorSettingsMaxSize(propertiesProvider) )) - } yield LoadFromFileSettings(settingsFile, settingsMaxSize) + } yield LoadFromFileParameters(settingsFile, settingsMaxSize) } - private implicit def loadFromIndexSettingsDecoder(propertiesProvider: PropertiesProvider): Decoder[LoadFromIndexSettings] = { + private implicit def loadFromIndexSettingsDecoder(propertiesProvider: PropertiesProvider): Decoder[LoadFromIndexParameters] = { for { settingsIndex <- rorSettingsIndexDecoder refreshInterval <- Decoder.instance(_ => Right(RorProperties.rorIndexSettingsReloadInterval(propertiesProvider))) @@ -212,7 +214,7 @@ object EsConfigBasedRorSettings { loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) settingsMaxSize <- Decoder.instance(_ => Right(RorProperties.rorSettingsMaxSize(propertiesProvider))) - } yield LoadFromIndexSettings( + } yield LoadFromIndexParameters( settingsIndex, refreshInterval, loadingAttemptsInterval, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala index 5b3a57d4d6..3c7719ab90 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala @@ -22,31 +22,32 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromFileSettings -import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslConfiguration, FipsMode, InternodeSslConfiguration} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromFileParameters +import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslSettings, FipsMode, InternodeSslSettings} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.SSLCertHelper -sealed trait RorSsl -object RorSsl extends Logging { +sealed trait RorSslSettings +object RorSslSettings extends Logging { - final case class OnlyExternalSslConfiguration(ssl: ExternalSslConfiguration) extends RorSsl - final case class OnlyInternodeSslConfiguration(ssl: InternodeSslConfiguration) extends RorSsl - final case class ExternalAndInternodeSslConfiguration(external: ExternalSslConfiguration, - internode: InternodeSslConfiguration) extends RorSsl + final case class OnlyExternalSslSettings(ssl: ExternalSslSettings) extends RorSslSettings + final case class OnlyInternodeSslSettings(ssl: InternodeSslSettings) extends RorSslSettings + final case class ExternalAndInternodeSslSettings(external: ExternalSslSettings, + internode: InternodeSslSettings) + extends RorSslSettings - implicit class ExtractSsl(val rorSsl: RorSsl) extends AnyVal { - def externalSsl: Option[ExternalSslConfiguration] = rorSsl match { - case OnlyExternalSslConfiguration(ssl) => Some(ssl) - case OnlyInternodeSslConfiguration(_) => None - case ExternalAndInternodeSslConfiguration(ssl, _) => Some(ssl) + implicit class ExtractSsl(val rorSsl: RorSslSettings) extends AnyVal { + def externalSsl: Option[ExternalSslSettings] = rorSsl match { + case OnlyExternalSslSettings(ssl) => Some(ssl) + case OnlyInternodeSslSettings(_) => None + case ExternalAndInternodeSslSettings(ssl, _) => Some(ssl) } - def internodeSsl: Option[InternodeSslConfiguration] = rorSsl match { - case OnlyExternalSslConfiguration(_) => None - case OnlyInternodeSslConfiguration(ssl) => Some(ssl) - case ExternalAndInternodeSslConfiguration(_, ssl) => Some(ssl) + def internodeSsl: Option[InternodeSslSettings] = rorSsl match { + case OnlyExternalSslSettings(_) => None + case OnlyInternodeSslSettings(ssl) => Some(ssl) + case ExternalAndInternodeSslSettings(_, ssl) => Some(ssl) } } @@ -57,38 +58,39 @@ object RorSsl extends Logging { } } - def load(esEnv: EsEnv, loadRorFromFileSettings: LoadFromFileSettings) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSsl]]] = Task { - implicit val sslDecoder: Decoder[Option[RorSsl]] = SslDecoders.rorSslDecoder(esEnv.configDir) + def load(esEnv: EsEnv, loadFromFileParameters: LoadFromFileParameters) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = Task { + implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esEnv.configDir) val esConfigFile = esEnv.elasticsearchYmlFile - loadSslConfigFromFile(esConfigFile) + loadSslSettingsFrom(esConfigFile) .fold( error => Left(error), { case None => - logger.info(s"Cannot find SSL configuration in ${esConfigFile.show} ...") - fallbackToRorConfig(loadRorFromFileSettings.rorSettingsFile) + logger.info(s"Cannot find ROR SSL settings in ${esConfigFile.show} ...") + fallbackToRorSettingsFile(loadFromFileParameters.rorSettingsFile) case Some(ssl) => Right(Some(ssl)) } ) } - private def fallbackToRorConfig(rorSettingsFile: File) - (implicit rorSslDecoder: Decoder[Option[RorSsl]], - systemContext: SystemContext) = { + private def fallbackToRorSettingsFile(rorSettingsFile: File) + (implicit decoder: Decoder[Option[RorSslSettings]], + systemContext: SystemContext) = { logger.info(s"... trying: ${rorSettingsFile.show}") if (rorSettingsFile.exists) { - loadSslConfigFromFile(rorSettingsFile) + loadSslSettingsFrom(rorSettingsFile) } else { Right(None) } } - private def loadSslConfigFromFile(configFile: File) - (implicit rorSslDecoder: Decoder[Option[RorSsl]], - systemContext: SystemContext) = { - new YamlFileBasedSettingsLoader(configFile).loadSettings[Option[RorSsl]](settingsName = "ROR SSL settings") + private def loadSslSettingsFrom(settingsFile: File) + (implicit decoder: Decoder[Option[RorSslSettings]], + systemContext: SystemContext) = { + new YamlFileBasedSettingsLoader(settingsFile) + .loadSettings[Option[RorSslSettings]](settingsName = "ROR SSL settings") } } @@ -139,25 +141,25 @@ object SslConfiguration { final case class FileBasedConfiguration(clientTrustedCertificateFile: ClientTrustedCertificateFile) extends ClientCertificateConfiguration } - final case class ExternalSslConfiguration(serverCertificateConfiguration: ServerCertificateConfiguration, - clientCertificateConfiguration: Option[ClientCertificateConfiguration], - allowedProtocols: Set[SslConfiguration.Protocol], - allowedCiphers: Set[SslConfiguration.Cipher], - clientAuthenticationEnabled: Boolean, - fipsMode: FipsMode) + final case class ExternalSslSettings(serverCertificateConfiguration: ServerCertificateConfiguration, + clientCertificateConfiguration: Option[ClientCertificateConfiguration], + allowedProtocols: Set[SslConfiguration.Protocol], + allowedCiphers: Set[SslConfiguration.Cipher], + clientAuthenticationEnabled: Boolean, + fipsMode: FipsMode) extends SslConfiguration { val certificateVerificationEnabled: Boolean = false } - final case class InternodeSslConfiguration(serverCertificateConfiguration: ServerCertificateConfiguration, - clientCertificateConfiguration: Option[ClientCertificateConfiguration], - allowedProtocols: Set[SslConfiguration.Protocol], - allowedCiphers: Set[SslConfiguration.Cipher], - clientAuthenticationEnabled: Boolean, - certificateVerificationEnabled: Boolean, - hostnameVerificationEnabled: Boolean, - fipsMode: FipsMode) + final case class InternodeSslSettings(serverCertificateConfiguration: ServerCertificateConfiguration, + clientCertificateConfiguration: Option[ClientCertificateConfiguration], + allowedProtocols: Set[SslConfiguration.Protocol], + allowedCiphers: Set[SslConfiguration.Cipher], + clientAuthenticationEnabled: Boolean, + certificateVerificationEnabled: Boolean, + hostnameVerificationEnabled: Boolean, + fipsMode: FipsMode) extends SslConfiguration sealed trait FipsMode @@ -278,7 +280,7 @@ private object SslDecoders extends Logging { } } - def rorSslDecoder(basePath: File): Decoder[Option[RorSsl]] = Decoder.instance { c => + def rorSslDecoder(basePath: File): Decoder[Option[RorSslSettings]] = Decoder.instance { c => implicit val isFipsCompliantDecoder: Decoder[FipsMode] = Decoder.decodeString.emap { case "NON_FIPS" => Right(FipsMode.NonFips) case "SSL_ONLY" => Right(FipsMode.SslOnly) @@ -288,24 +290,24 @@ private object SslDecoders extends Logging { fipsMode <- c.downField(consts.rorSection).downField(consts.fipsMode).as[Option[FipsMode]] interNodeSsl <- { implicit val internodeSslConfigDecoder = sslInternodeConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) - c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslConfiguration]]] + c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslSettings]]] } externalSsl <- { implicit val externalSslConfigDecoder = sslExternalConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) - c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslConfiguration]]] + c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslSettings]]] } } yield { (externalSsl.flatten, interNodeSsl.flatten) match { - case (Some(ssl), None) => Some(RorSsl.OnlyExternalSslConfiguration(ssl)) - case (None, Some(ssl)) => Some(RorSsl.OnlyInternodeSslConfiguration(ssl)) - case (Some(externalSsl), Some(internalSsl)) => Some(RorSsl.ExternalAndInternodeSslConfiguration(externalSsl, internalSsl)) + case (Some(ssl), None) => Some(RorSslSettings.OnlyExternalSslSettings(ssl)) + case (None, Some(ssl)) => Some(RorSslSettings.OnlyInternodeSslSettings(ssl)) + case (Some(externalSsl), Some(internalSsl)) => Some(RorSslSettings.ExternalAndInternodeSslSettings(externalSsl, internalSsl)) case (None, None) => None } } } private def sslInternodeConfigurationDecoder(basePath: File, - fipsMode: FipsMode): Decoder[Option[InternodeSslConfiguration]] = Decoder.instance { c => + fipsMode: FipsMode): Decoder[Option[InternodeSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { certificateVerification <- c.downField(consts.certificateVerification).as[Option[Boolean]] @@ -313,7 +315,7 @@ private object SslDecoders extends Logging { verification <- c.downField(consts.verification).as[Option[Boolean]] sslCommonProperties <- sslCommonPropertiesDecoder(basePath, c) } yield - InternodeSslConfiguration( + InternodeSslSettings( serverCertificateConfiguration = sslCommonProperties.serverCertificateConfiguration, clientCertificateConfiguration = sslCommonProperties.clientCertificateConfiguration, allowedProtocols = sslCommonProperties.allowedProtocols, @@ -327,13 +329,13 @@ private object SslDecoders extends Logging { } private def sslExternalConfigurationDecoder(basePath: File, - fipsMode: FipsMode): Decoder[Option[ExternalSslConfiguration]] = Decoder.instance { c => + fipsMode: FipsMode): Decoder[Option[ExternalSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { verification <- c.downField(consts.verification).as[Option[Boolean]] sslCommonProperties <- sslCommonPropertiesDecoder(basePath, c) } yield - ExternalSslConfiguration( + ExternalSslSettings( serverCertificateConfiguration = sslCommonProperties.serverCertificateConfiguration, clientCertificateConfiguration = sslCommonProperties.clientCertificateConfiguration, allowedProtocols = sslCommonProperties.allowedProtocols, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index 541289917a..eb3cc59ec0 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -18,7 +18,7 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.RorConfigurationIndex +import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexMainSettingsManager.Const import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} @@ -29,7 +29,7 @@ import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -final class IndexJsonContentServiceBasedIndexMainSettingsManager(settingsIndex: RorConfigurationIndex, +final class IndexJsonContentServiceBasedIndexMainSettingsManager(settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[RawRorSettings] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index dbe3f358dc..be6e11c87d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthoriza import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.LdapUserMock import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId -import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorConfigurationIndex, User} +import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} import tech.beshu.ror.configuration.TestRorSettings.Present import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexTestSettingsManager.Const import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} @@ -51,7 +51,7 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -final class IndexJsonContentServiceBasedIndexTestSettingsManager(settingsIndex: RorConfigurationIndex, +final class IndexJsonContentServiceBasedIndexTestSettingsManager(settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[TestRorSettings] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala index cee1798847..9323780a27 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala @@ -20,7 +20,7 @@ import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileSettings, LoadFromIndexSettings} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParameters, LoadFromIndexParameters} import tech.beshu.ror.configuration.RorProperties.LoadingAttemptsCount import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError @@ -35,53 +35,51 @@ import scala.language.postfixOps class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSettings]) extends Logging { - def loadFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { - forceLoadFromFile(settings) + def loadFromFile(loadFromFileParameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + forceLoadFromFile(loadFromFileParameters) } - def loadFromIndexWithFileFallback(indexLoadingSettings: LoadFromIndexSettings, - fallbackFileLoadingSettings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + def loadFromIndexWithFileFallback(loadFromIndexParameters: LoadFromIndexParameters, + loadFromFileParameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { attemptLoadingFromIndex( - settings = indexLoadingSettings, - fallback = loadRorSettingsFromFile(fallbackFileLoadingSettings) + parameters = loadFromIndexParameters, + fallback = loadRorSettingsFromFile(loadFromFileParameters) ) } - private def attemptLoadingFromIndex(settings: LoadFromIndexSettings, + private def attemptLoadingFromIndex(parameters: LoadFromIndexParameters, fallback: Task[Either[RorMainSettingsManager.Error, RawRorSettings]]): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { - settings.loadingAttemptsCount.value.value match { + parameters.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => - for { - result <- loadRorConfigFromIndex(settings) - rawRorConfig <- result match { - case Left(RorMainSettingsManager.IndexNotExist) => - attemptLoadingFromIndex( - settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback - ) - case Left(RorMainSettingsManager.IndexUnknownStructure) => - Task.now(Left(RorMainSettingsManager.IndexUnknownStructure)) - case Left(error@RorMainSettingsManager.IndexParsingError(_)) => - Task.now(Left(error)) - case Right(value) => - Task.now(Right(value)) - } - } yield rawRorConfig + loadRorSettingsFromIndex(parameters).flatMap { + case Left(RorMainSettingsManager.IndexNotExist) => + attemptLoadingFromIndex( + parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), + fallback = fallback + ) + case Left(RorMainSettingsManager.IndexUnknownStructure) => + Task.now(Left(RorMainSettingsManager.IndexUnknownStructure)) + case Left(error@RorMainSettingsManager.IndexParsingError(_)) => + Task.now(Left(error)) + case Right(value) => + Task.now(Right(value)) + } } } - private def loadRorConfigFromIndex(settings: LoadFromIndexSettings) = { - val rorConfigIndex = settings.rorConfigIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorConfigIndex.index.show}) ...") + private def loadRorSettingsFromIndex(parameters: LoadFromIndexParameters) = { + val rorSettingsIndex = parameters.rorSettingsIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorSettingsIndex.index.show}) ...") EitherT { indexSettingsManager .load() - .delayExecution(settings.loadingDelay.value.value) - }.map { rawRorConfig => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw config from index: ${rawRorConfig.raw.show}") - rawRorConfig + .delayExecution(parameters.loadingDelay.value.value) + } + .map { rorSettings => + logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw ReadonlyREST settings from index: ${rorSettings.raw.show}") + rorSettings } .leftMap { error => val newError = convertIndexError(error) @@ -92,9 +90,9 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } // todo: these two are almost the same (logging differs only) - private def loadRorSettingsFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { - val rorSettingsFile = settings.rorSettingsFile - val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + val rorSettingsFile = parameters.rorSettingsFile + val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) .leftMap { error => @@ -105,9 +103,9 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe .value } - private def forceLoadFromFile(settings: LoadFromFileSettings): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { - val rorSettingsFile = settings.rorSettingsFile - val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(settings.settingsMaxSize) + private def forceLoadFromFile(parameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + val rorSettingsFile = parameters.rorSettingsFile + val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) .leftMap { error => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala index b0bf092760..e30db03425 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.configuration.loader import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexSettings +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.TestRorSettings import tech.beshu.ror.configuration.index.IndexSettingsManager @@ -34,7 +34,7 @@ import scala.language.postfixOps class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSettings]) extends Logging { - def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexSettings, + def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexParameters, fallbackConfig: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { attemptLoadingConfigFromIndex( settings = indexLoadingSettings, @@ -42,7 +42,7 @@ class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSett ) } - private def attemptLoadingConfigFromIndex(settings: LoadFromIndexSettings, + private def attemptLoadingConfigFromIndex(settings: LoadFromIndexParameters, fallback: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { settings.loadingAttemptsCount.value.value match { case 0 => @@ -69,8 +69,8 @@ class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSett } } - private def loadTestRorConfigFromIndex(settings: LoadFromIndexSettings) = { - val rorConfigIndex = settings.rorConfigIndex + private def loadTestRorConfigFromIndex(settings: LoadFromIndexParameters) = { + val rorConfigIndex = settings.rorSettingsIndex val loadingDelay = settings.loadingDelay // todo: log is ok? logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 544ae3e7d6..91ddec4bc9 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler.Implicits.global import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} @@ -54,7 +54,7 @@ trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { core <- factory .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), httpClientsFactory, ldapConnectionPoolProvider, mockProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala index e3687b1269..b4e5252e2d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala @@ -154,7 +154,7 @@ class EnabledAccessControlListTests extends AnyWordSpec with MockFactory with In showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden", flsEngine = FlsEngine.default, - configurationIndex = RorConfigurationIndex(IndexName.Full(".readonlyrest")), + configurationIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala index ae79f7fb54..bae2307862 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala @@ -122,7 +122,7 @@ class UserDefinitionsValidatorTests extends AnyWordSpec with Matchers { showBasicAuthPrompt = false, forbiddenRequestMessage = "Forbidden", flsEngine = GlobalSettings.FlsEngine.default, - configurationIndex = RorConfigurationIndex(IndexName.Full(nes(".readonlyrest"))), + configurationIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = validationEnabled ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaAccessRuleTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaAccessRuleTests.scala index 0b233b226c..fce23af245 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaAccessRuleTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaAccessRuleTests.scala @@ -30,7 +30,7 @@ class KibanaAccessRuleTests override protected def settingsOf(access: KibanaAccess, customKibanaIndex: Option[KibanaIndexName] = None): Settings = - Settings(access, RorConfigurationIndex(rorIndex)) + Settings(access, RorSettingsIndex(rorIndex)) override protected def defaultOutputBlockContextAssertion(settings: Settings, indices: Set[RequestedIndex[ClusterIndexName]], diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala index e88d5de7b5..fb58caf0ca 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/KibanaUserDataRuleTests.scala @@ -58,7 +58,7 @@ class KibanaUserDataRuleTests appsToHide = Set.empty, allowedApiPaths = Set.empty, metadata = None, - rorIndex = RorConfigurationIndex(rorIndex) + rorIndex = RorSettingsIndex(rorIndex) )) val blockContext = checkRule(rule) blockContext.userMetadata should be { @@ -82,7 +82,7 @@ class KibanaUserDataRuleTests appsToHide = apps.toCovariantSet, allowedApiPaths = Set.empty, metadata = None, - rorIndex = RorConfigurationIndex(rorIndex) + rorIndex = RorSettingsIndex(rorIndex) )) val blockContext = checkRule(rule) blockContext.userMetadata should be { @@ -119,7 +119,7 @@ class KibanaUserDataRuleTests appsToHide = Set.empty, allowedApiPaths = paths.toCovariantSet, metadata = None, - rorIndex = RorConfigurationIndex(rorIndex) + rorIndex = RorSettingsIndex(rorIndex) )) val blockContext = checkRule(rule) blockContext.userMetadata should be { @@ -161,7 +161,7 @@ class KibanaUserDataRuleTests appsToHide = Set.empty, allowedApiPaths = Set.empty, metadata = Option(resolvableMetadataJsonRepresentation), - rorIndex = RorConfigurationIndex(rorIndex) + rorIndex = RorSettingsIndex(rorIndex) )) val blockContext = checkRule(rule) blockContext.userMetadata should be { @@ -226,7 +226,7 @@ class KibanaUserDataRuleTests appsToHide = Set.empty, allowedApiPaths = Set.empty, metadata = None, - rorIndex = RorConfigurationIndex(rorIndex) + rorIndex = RorSettingsIndex(rorIndex) ) override protected def defaultOutputBlockContextAssertion(settings: KibanaUserDataRule.Settings, diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index a00a92f2db..c51781a318 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink.Config import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.AuditCluster.{LocalAuditCluster, RemoteAuditCluster} -import tech.beshu.ror.accesscontrol.domain.{AuditCluster, IndexName, RorAuditLoggerName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{AuditCluster, IndexName, RorAuditLoggerName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.AuditingSettingsCreationError import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.{Core, RawRorConfigBasedCoreFactory} @@ -172,7 +172,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -829,7 +829,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -888,7 +888,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1681,7 +1681,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1694,7 +1694,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1712,7 +1712,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1741,7 +1741,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory(esVersion) .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1768,7 +1768,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider @@ -1795,7 +1795,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory(esVersion) .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index c093ebcd20..5c3749e2b3 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -26,7 +26,7 @@ import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.EnabledAccessControlList import tech.beshu.ror.accesscontrol.blocks.Block import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider -import tech.beshu.ror.accesscontrol.domain.{Header, IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{Header, IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} @@ -487,7 +487,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { factory .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 3ce29fbaa6..3c5812cd8d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationSe import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} -import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.MockHttpClientsFactory @@ -377,7 +377,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { factory .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, new UnboundidLdapConnectionPoolProvider(), mocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index eca282accb..2e8cc87440 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -22,7 +22,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider -import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorConfigurationIndex, User} +import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorSettingsIndex, User} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} @@ -309,7 +309,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { factory .createCoreFrom( config, - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, ldapConnectionPoolProvider, NoOpMocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala index ae78d0a323..74b9032414 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala @@ -18,7 +18,7 @@ package tech.beshu.ror.unit.acl.factory.decoders.definitions import eu.timepit.refined.types.string.NonEmptyString import org.scalatest.matchers.should.Matchers.* -import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.GeneralReadonlyrestSettingsError @@ -504,6 +504,6 @@ class GlobalSettingsTests private object GlobalSettingsTests { val decoder: SyncDecoder[GlobalSettings] = SyncDecoderCreator.from( - GlobalStaticSettingsDecoder.instance(RorConfigurationIndex(IndexName.Full(NonEmptyString.unsafeFrom(".readonlyrest")))) + GlobalStaticSettingsDecoder.instance(RorSettingsIndex(IndexName.Full(NonEmptyString.unsafeFrom(".readonlyrest")))) ) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala index 948ad463ce..3d8a0d843a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala @@ -22,7 +22,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationSe import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.blocks.rules.auth.{AuthKeyRule, AuthKeySha1Rule} import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern -import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorConfigurationIndex, User, UserIdPatterns} +import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex, User, UserIdPatterns} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError @@ -37,7 +37,7 @@ class ImpersonationSettingsTests extends BaseDecoderTest( showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden by ReadonlyREST", flsEngine = FlsEngine.ES, - configurationIndex = RorConfigurationIndex(fullIndexName(".readonlyrest")), + configurationIndex = RorSettingsIndex(fullIndexName(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala index 671687789a..d159392650 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala @@ -26,7 +26,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.* import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.* import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.blocks.rules.Rule -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.factory.{Core, HttpClientsFactory, RawRorConfigBasedCoreFactory} import tech.beshu.ror.SystemContext @@ -62,7 +62,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord aFactory .createCoreFrom( rorConfigFromUnsafe(yaml), - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), httpClientsFactory, ldapConnectionPoolProvider, mocksProvider @@ -85,7 +85,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord aFactory .createCoreFrom( rorConfigFromUnsafe(yaml), - RorConfigurationIndex(IndexName.Full(".readonlyrest")), + RorSettingsIndex(IndexName.Full(".readonlyrest")), httpClientsFactory, ldapConnectionPoolProvider, mocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala index 957d5a70bd..4c14efb2e4 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala @@ -22,7 +22,7 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.UsersRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.* -import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorConfigurationIndex, User} +import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorSettingsIndex, User} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue @@ -38,7 +38,7 @@ class UsersRuleSettingsTests extends BaseRuleSettingsDecoderTest[UsersRule] { showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden", flsEngine = FlsEngine.default, - configurationIndex = RorConfigurationIndex(IndexName.Full(".readonlyrest")), + configurationIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala index 802f898ec3..3698a0b6b0 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala @@ -18,7 +18,7 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.kibana import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaAccessRule -import tech.beshu.ror.accesscontrol.domain.{IndexName, KibanaAccess, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, KibanaAccess, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest @@ -42,7 +42,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.RO) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -60,7 +60,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.RW) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -78,7 +78,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.ROStrict) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -96,7 +96,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.Admin) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -114,7 +114,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.ApiOnly) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -132,7 +132,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc |""".stripMargin, assertion = rule => { rule.settings.access should be(KibanaAccess.Unrestricted) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala index 62c2952bbf..1e1def09eb 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala @@ -60,7 +60,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -89,7 +89,7 @@ class KibanaUserDataRuleSettingsTests Set(KibanaAllowedApiPath(AllowedHttpMethod.Any, JavaRegex.compile("""^/api/spaces/.*$""").get)) ) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -113,7 +113,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -136,7 +136,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -159,7 +159,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -182,7 +182,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -204,7 +204,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.kibanaTemplateIndex should be(None) rule.settings.appsToHide should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -227,7 +227,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -253,7 +253,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set(FullNameKibanaApp("app1"))) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -280,7 +280,7 @@ class KibanaUserDataRuleSettingsTests )) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -304,7 +304,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -332,7 +332,7 @@ class KibanaUserDataRuleSettingsTests Set(KibanaAllowedApiPath(AllowedHttpMethod.Any, JavaRegex.compile("""^/api/spaces/.*$""").get)) ) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -361,7 +361,7 @@ class KibanaUserDataRuleSettingsTests )) ) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -392,7 +392,7 @@ class KibanaUserDataRuleSettingsTests )) ) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -428,7 +428,7 @@ class KibanaUserDataRuleSettingsTests ) )) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -452,7 +452,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -479,7 +479,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -505,7 +505,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(None) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -553,7 +553,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(Some(resolvableMetadataJsonRepresentation)) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } @@ -577,7 +577,7 @@ class KibanaUserDataRuleSettingsTests rule.settings.appsToHide should be(Set.empty) rule.settings.allowedApiPaths should be(Set.empty) rule.settings.metadata should be(Some(JsonTree.Value(AlreadyResolved(NullValue)))) - rule.settings.rorIndex should be(RorConfigurationIndex(IndexName.Full(".readonlyrest"))) + rule.settings.rorIndex should be(RorSettingsIndex(IndexName.Full(".readonlyrest"))) } ) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala index 09b96fb579..85c28f9a43 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala @@ -21,7 +21,7 @@ import io.circe.Json import org.scalatest.EitherValues import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction.* import tech.beshu.ror.configuration.RawRorSettings @@ -145,7 +145,7 @@ object LoadRawRorSettingsTest { private val esEnv = EsEnv(Paths.get("unused_file_path"), Paths.get("unused_file_path"), defaultEsVersionForTests) private val rawRorConfig = RawRorSettings(Json.False, "forced file config") - private val rorConfigurationIndex = RorConfigurationIndex(IndexName.Full("rorConfigurationIndex")) + private val rorConfigurationIndex = RorSettingsIndex(IndexName.Full("rorConfigurationIndex")) } object IdCompiler { diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala index 32f9a9e2ab..95f1a8aa14 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala @@ -22,7 +22,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.configuration.SslConfiguration.* import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} -import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorSsl} +import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorSslSettings} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} @@ -37,9 +37,9 @@ class SslConfigurationTest "A ReadonlyREST ES API SSL settings" should { "be loaded from elasticsearch config file" when { "all properties contain at least one non-digit" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get inside(ssl.externalSsl) { - case Some(ExternalSslConfiguration(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => keystoreFile.value.getName should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -52,9 +52,9 @@ class SslConfigurationTest ssl.interNodeSsl should be(None) } "some properties contains only digits" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/")).runSyncUnsafe().toOption.get inside(ssl.externalSsl) { - case Some(ExternalSslConfiguration(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => keystoreFile.value.getName should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("123456")) keyPass should be(KeyPass("12")) @@ -67,9 +67,9 @@ class SslConfigurationTest ssl.interNodeSsl should be(None) } "server and client are configured using pem files" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get inside(ssl.externalSsl) { - case Some(ExternalSslConfiguration(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => + case Some(ExternalSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => serverCertificateKeyFile.value.getName should be("server_certificate_key.pem") serverCertificateFile.value.getName should be("server_certificate.pem") clientTrustedCertificateFile.value.getName should be("client_certificate.pem") @@ -81,9 +81,9 @@ class SslConfigurationTest } "be loaded from readonlyrest config file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get inside(ssl.externalSsl) { - case Some(ExternalSslConfiguration(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => keystoreFile.value.getName should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -98,12 +98,12 @@ class SslConfigurationTest } "be disabled" when { "no ssl section is provided" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/no_es_api_ssl_settings/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/no_es_api_ssl_settings/")).runSyncUnsafe().toOption.get ssl.externalSsl should be(None) ssl.interNodeSsl should be(None) } "it's disabled by proper settings" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_disabled/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_disabled/")).runSyncUnsafe().toOption.get ssl.externalSsl should be(None) ssl.interNodeSsl should be(None) } @@ -113,13 +113,13 @@ class SslConfigurationTest "keystore_file entry is missing" in { val configFolderPath = "/boot_tests/es_api_ssl_settings_malformed/" val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorSsl.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings(s"Cannot load ROR SSL configuration from file $expectedFilePath. Cause: Missing required field") } } } "file content is not valid yaml" in { - val error = RorSsl.load(esEnvFrom("/boot_tests/es_api_ssl_settings_file_invalid_yaml/")).runSyncUnsafe() + val error = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_file_invalid_yaml/")).runSyncUnsafe() inside(error) { case Left(error) => error.message should startWith("Cannot parse file") @@ -130,7 +130,7 @@ class SslConfigurationTest val configFolderPath = "/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/" val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorSsl.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( s"Cannot load ROR SSL configuration from file $expectedFilePath. " + s"Cause: Field sets [server_certificate_key_file, server_certificate_file] and [keystore_file, keystore_pass, key_pass, key_alias] could not be present in the same configuration section") @@ -141,9 +141,9 @@ class SslConfigurationTest "A ReadonlyREST internode SSL settings" should { "be loaded from elasticsearch config file" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get inside(ssl.interNodeSsl) { - case Some(InternodeSslConfiguration(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => + case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => keystoreFile.value.getName should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -157,9 +157,9 @@ class SslConfigurationTest ssl.externalSsl should be(None) } "be loaded from elasticsearch config file when pem files are used" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/internode_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get inside(ssl.interNodeSsl) { - case Some(InternodeSslConfiguration(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => + case Some(InternodeSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => serverCertificateKeyFile.value.getName should be("server_certificate_key.pem") serverCertificateFile.value.getName should be("server_certificate.pem") clientTrustedCertificateFile.value.getName should be("client_certificate.pem") @@ -172,9 +172,9 @@ class SslConfigurationTest } "be loaded from readonlyrest config file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get inside(ssl.interNodeSsl) { - case Some(InternodeSslConfiguration(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => + case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => keystoreFile.value.getName should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -191,12 +191,12 @@ class SslConfigurationTest } "be disabled" when { "no ssl section is provided" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/no_internode_ssl_settings/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/no_internode_ssl_settings/")).runSyncUnsafe().toOption.get ssl.externalSsl should be(None) ssl.interNodeSsl should be(None) } "it's disabled by proper settings" in { - val ssl = RorSsl.load(esEnvFrom("/boot_tests/internode_ssl_settings_disabled/")).runSyncUnsafe().toOption.get + val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_disabled/")).runSyncUnsafe().toOption.get ssl.externalSsl should be(None) ssl.interNodeSsl should be(None) } @@ -206,7 +206,7 @@ class SslConfigurationTest "keystore_file entry is missing" in { val configFolderPath = "/boot_tests/internode_ssl_settings_malformed/" val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorSsl.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings(s"Cannot load ROR SSL configuration from file $expectedFilePath. Cause: Missing required field") } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala index 51451dd7ab..b96da1ac02 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala @@ -20,7 +20,7 @@ import cats.implicits.* import eu.timepit.refined.types.string.NonEmptyString import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorConfigurationIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.configuration.loader.LoadedRorConfig import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.configuration.loader.distributed.Summary.CurrentNodeHaveToProduceResult @@ -170,5 +170,5 @@ class SummaryTest extends AnyWordSpec { } } - private def configIndex(value: NonEmptyString) = RorConfigurationIndex(IndexName.Full(value)) + private def configIndex(value: NonEmptyString) = RorSettingsIndex(IndexName.Full(value)) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index d3ce42e587..369e81dc3c 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage import tech.beshu.ror.configuration.EsConfigBasedRorSettings -import tech.beshu.ror.configuration.RorSsl.IsSslFipsCompliant +import tech.beshu.ror.configuration.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 1f00261ee4..5dd4a49759 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.configuration.SslConfiguration.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,7 +36,7 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, tracer: Tracer, diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..cad324634e 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.configuration.SslConfiguration.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,7 +42,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, + ssl: InternodeSslSettings, sharedGroupFactory: SharedGroupFactory, fipsCompliant: Boolean) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) From 9a80d9f7a6333b2dd7a00b875147cd80026ce458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 11 Jul 2025 13:22:52 +0200 Subject: [PATCH 015/103] refactoring --- .../ror/accesscontrol/blocks/Block.scala | 4 +- .../accesscontrol/factory/CoreFactory.scala | 58 ++-- .../decoders/AuditingSettingsDecoder.scala | 4 +- .../GlobalStaticSettingsDecoder.scala | 4 +- .../factory/decoders/common.scala | 6 +- .../definitions/DefinitionsBaseDecoder.scala | 4 +- ...xternalAuthenticationServicesDecoder.scala | 6 +- ...ExternalAuthorizationServicesDecoder.scala | 4 +- ...personationDefinitionsDecoderCreator.scala | 4 +- .../definitions/JwtDefinitionsDecoder.scala | 6 +- .../definitions/LdapServicesDecoder.scala | 6 +- .../ProxyAuthDefinitionsDecoder.scala | 4 +- .../RorKbnDefinitionsDecoder.scala | 6 +- .../definitions/UsersDefinitionsDecoder.scala | 6 +- ...nsformationAliasesDefinitionsDecoder.scala | 2 +- .../factory/decoders/ruleDecoders.scala | 2 +- .../decoders/rules/RuleBaseDecoder.scala | 4 +- .../rules/auth/AuthKeyRulesDecoders.scala | 4 +- .../ExternalAuthenticationRuleDecoder.scala | 6 +- .../ExternalAuthorizationRuleDecoder.scala | 6 +- .../rules/auth/JwtAuthRuleDecoder.scala | 4 +- .../rules/auth/LdapRulesDecoders.scala | 6 +- .../rules/auth/ProxyAuthRuleDecoder.scala | 4 +- .../rules/auth/RorKbnAuthRuleDecoder.scala | 4 +- .../auth/groups/BaseGroupsRuleDecoder.scala | 4 +- .../GroupsLogicRepresentationDecoder.scala | 4 +- .../rules/auth/groups/GroupsRuleDecoder.scala | 4 +- .../DataStreamsRuleDecoder.scala | 4 +- .../FieldsRuleLikeDecoderHelperBase.scala | 6 +- .../elasticsearch/IndicesRulesDecoders.scala | 4 +- .../RepositoriesRuleDecoder.scala | 4 +- .../elasticsearch/SnapshotsRuleDecoder.scala | 4 +- .../rules/http/MaxBodyLengthRuleDecoder.scala | 4 +- .../rules/http/MethodsRuleDecoder.scala | 4 +- .../http/SessionMaxIdleRuleDecoder.scala | 2 +- .../rules/http/UriRegexRuleDecoder.scala | 4 +- .../kibana/KibanaUserDataRuleDecoder.scala | 6 +- .../ror/accesscontrol/utils/ADecoder.scala | 4 +- .../ror/accesscontrol/utils/CirceOps.scala | 6 +- .../tech/beshu/ror/api/AuthMockApi.scala | 16 +- .../scala/tech/beshu/ror/api/ConfigApi.scala | 210 -------------- .../beshu/ror/api/MainRorSettingsApi.scala | 206 ++++++++++++++ .../tech/beshu/ror/api/TestConfigApi.scala | 267 ------------------ .../beshu/ror/api/TestRorSettingsApi.scala | 267 ++++++++++++++++++ .../tech/beshu/ror/boot/ReadonlyRest.scala | 140 ++++----- .../tech/beshu/ror/boot/RorInstance.scala | 231 ++++++++------- .../boot/engines/BaseReloadableEngine.scala | 40 +-- ...> MainSettingsBasedReloadableEngine.scala} | 77 ++--- ...> TestSettingsBasedReloadableEngine.scala} | 126 ++++----- .../EsConfigBasedRorSettings.scala | 2 +- .../ror/configuration/RorProperties.scala | 2 + .../ror/configuration/TestRorSettings.scala | 4 +- ...ServiceBasedIndexMainSettingsManager.scala | 2 +- ...ServiceBasedIndexTestSettingsManager.scala | 4 +- .../index/IndexSettingsManager.scala | 3 + .../loader/RorMainSettingsManager.scala | 93 +++--- ...der.scala => RorTestSettingsManager.scala} | 96 ++++--- .../loader/SettingsManager.scala | 51 ++++ .../tech/beshu/ror/utils/RefinedUtils.scala | 4 +- .../BaseYamlLoadedAccessControlTest.scala | 4 +- .../unit/acl/factory/AuditSettingsTests.scala | 8 +- .../unit/acl/factory/CoreFactoryTests.scala | 8 +- .../factory/ImpersonationWarningsTests.scala | 4 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 4 +- .../definitions/BaseDecoderTest.scala | 2 +- .../definitions/GlobalSettingsTests.scala | 4 +- .../ImpersonationSettingsTests.scala | 4 +- .../LdapServicesSettingsTests.scala | 4 +- .../VariableTransformationAliasesTests.scala | 4 +- .../rules/BaseRuleSettingsDecoderTest.scala | 12 +- .../rules/auth/ApiKeysRuleSettingsTests.scala | 4 +- ...BKDF2WithHmacSHA512RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha1RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha256RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha512RuleSettingsTests.scala | 4 +- ...ernalAuthenticationRuleSettingsTests.scala | 4 +- ...ternalAuthorizationRuleSettingsTests.scala | 4 +- .../rules/auth/GroupsRuleSettingsTests.scala | 4 +- .../rules/auth/JwtAuthRuleSettingsTests.scala | 4 +- .../auth/LdapAuthRuleSettingsTests.scala | 4 +- .../LdapAuthenticationRuleSettingsTests.scala | 4 +- .../LdapAuthorizationRuleSettingsTests.scala | 4 +- .../auth/ProxyAuthRuleSettingsTests.scala | 4 +- .../auth/RorKbnAuthRuleSettingsTests.scala | 4 +- ...TokenAuthenticationRuleSettingsTests.scala | 4 +- .../rules/auth/UsersRuleSettingsTests.scala | 4 +- .../ActionRuleSettingsTests.scala | 4 +- .../DataStreamsRuleSettingsTest.scala | 4 +- .../FieldsRuleSettingsTest.scala | 4 +- .../FilterRuleSettingsTests.scala | 4 +- .../IndicesRuleSettingsTests.scala | 4 +- .../RepositoriesRuleSettingsTest.scala | 4 +- .../ResponseFieldsRuleSettingsTest.scala | 4 +- .../SnapshotsRuleSettingsTest.scala | 4 +- .../http/HeadersAndRuleSettingsTests.scala | 4 +- .../http/HeadersOrRuleSettingsTests.scala | 4 +- .../http/MaxBodyLengthRuleSettingsTests.scala | 4 +- .../rules/http/MethodsRuleSettingsTests.scala | 4 +- .../SessionMaxIdleRuleSettingsTests.scala | 4 +- .../http/UriRegexRuleSettingsTests.scala | 4 +- .../http/XForwardedForRuleSettingsTests.scala | 4 +- .../KibanaAccessRuleSettingsTests.scala | 4 +- .../KibanaHideAppsRuleSettingsTests.scala | 4 +- .../kibana/KibanaIndexRuleSettingsTests.scala | 4 +- .../KibanaUserDataRuleSettingsTests.scala | 4 +- .../transport/HostsRuleSettingsTests.scala | 4 +- .../LocalHostsRuleSettingsTests.scala | 4 +- .../unit/boot/ReadonlyRestStartingTests.scala | 202 ++++++------- .../beshu/ror/unit/boot/RorIndexTest.scala | 10 +- .../rradmin/RRAdminActionHandler.scala | 6 +- .../es/actions/rradmin/RRAdminRequest.scala | 16 +- .../es/actions/rradmin/RRAdminResponse.scala | 44 +-- .../RRTestConfigActionHandler.scala | 6 +- .../rrtestconfig/RRTestConfigRequest.scala | 16 +- .../rrtestconfig/RRTestConfigResponse.scala | 38 +-- 115 files changed, 1342 insertions(+), 1271 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala create mode 100644 core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala create mode 100644 core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala rename core/src/main/scala/tech/beshu/ror/boot/engines/{MainConfigBasedReloadableEngine.scala => MainSettingsBasedReloadableEngine.scala} (59%) rename core/src/main/scala/tech/beshu/ror/boot/engines/{TestConfigBasedReloadableEngine.scala => TestSettingsBasedReloadableEngine.scala} (62%) rename core/src/main/scala/tech/beshu/ror/configuration/loader/{RorTestSettingsLoader.scala => RorTestSettingsManager.scala} (52%) create mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/Block.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/Block.scala index 3b6a520747..24c9bddb09 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/Block.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/Block.scala @@ -31,8 +31,8 @@ import tech.beshu.ror.accesscontrol.blocks.users.LocalUsersContext.LocalUsersSup import tech.beshu.ror.accesscontrol.blocks.variables.runtime.VariableContext.VariableUsage import tech.beshu.ror.accesscontrol.factory.BlockValidator import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.BlocksLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.BlocksLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index 6baec1aa09..2ed8dae92f 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -39,9 +39,9 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVa import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} import tech.beshu.ror.accesscontrol.domain.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.* +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.* +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RorDependencies.ImpersonationWarningsReader import tech.beshu.ror.accesscontrol.factory.decoders.definitions.* import tech.beshu.ror.accesscontrol.factory.decoders.ruleDecoders.ruleDecoderBy @@ -69,8 +69,8 @@ trait CoreFactory { mocksProvider: MocksProvider): Task[Either[NonEmptyList[CoreCreationError], Core]] } -class RawRorConfigBasedCoreFactory(esVersion: EsVersion) - (implicit systemContext: SystemContext) +class RawRorSettingsBasedCoreFactory(esVersion: EsVersion) + (implicit systemContext: SystemContext) extends CoreFactory with Logging { override def createCoreFrom(rorSettings: RawRorSettings, @@ -127,14 +127,14 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) val decoder = for { enabled <- AsyncDecoderCreator.from(coreEnabilityDecoder) core <- - if (!enabled) { - AsyncDecoderCreator.from(Decoder.const(Core(DisabledAccessControlList, RorDependencies.noOp, None))) - } else { - for { - globalSettings <- AsyncDecoderCreator.from(GlobalStaticSettingsDecoder.instance(rorConfigurationIndex)) - core <- coreDecoder(httpClientFactory, ldapConnectionPoolProvider, globalSettings, mocksProvider) - } yield core - } + if (!enabled) { + AsyncDecoderCreator.from(Decoder.const(Core(DisabledAccessControlList, RorDependencies.noOp, None))) + } else { + for { + globalSettings <- AsyncDecoderCreator.from(GlobalStaticSettingsDecoder.instance(rorConfigurationIndex)) + core <- coreDecoder(httpClientFactory, ldapConnectionPoolProvider, globalSettings, mocksProvider) + } yield core + } } yield core decoder(HCursor.fromJson(settingsJson)) @@ -148,7 +148,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) } } - import RawRorConfigBasedCoreFactory.* + import RawRorSettingsBasedCoreFactory.* private def rulesNelDecoder(definitions: DefinitionsPack, globalSettings: GlobalSettings, @@ -157,15 +157,15 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) val (_, result) = c.keys.toList.flatten // at the moment kibana_index must be defined before kibana_access .foldLeft(init) { case (collectedRuleResults, currentRuleName) => - for { - last <- collectedRuleResults - current <- decodeRuleInCursorContext(currentRuleName, definitions, globalSettings, mocksProvider).map { - case RuleDecodingResult.Result(value) => Validated.Valid(value.map(_ :: Nil)) - case RuleDecodingResult.UnknownRule => Validated.Invalid(currentRuleName :: Nil) - case RuleDecodingResult.Skipped => Validated.Valid(Right(List.empty)) - } - } yield Monoid.combine(last, current) - } + for { + last <- collectedRuleResults + current <- decodeRuleInCursorContext(currentRuleName, definitions, globalSettings, mocksProvider).map { + case RuleDecodingResult.Result(value) => Validated.Valid(value.map(_ :: Nil)) + case RuleDecodingResult.UnknownRule => Validated.Invalid(currentRuleName :: Nil) + case RuleDecodingResult.Skipped => Validated.Valid(Right(List.empty)) + } + } yield Monoid.combine(last, current) + } .run(c) .value @@ -218,10 +218,10 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) .decodeString .toSyncDecoder .emapE[Verbosity] { - case "info" => Right(Verbosity.Info) - case "error" => Right(Verbosity.Error) - case unknown => Left(BlocksLevelCreationError(Message(s"Unknown verbosity value: ${unknown.show}. Supported types: 'info'(default), 'error'."))) - } + case "info" => Right(Verbosity.Info) + case "error" => Right(Verbosity.Error) + case unknown => Left(BlocksLevelCreationError(Message(s"Unknown verbosity value: ${unknown.show}. Supported types: 'info'(default), 'error'."))) + } .decoder Decoder .instance { c => @@ -456,7 +456,7 @@ class RawRorConfigBasedCoreFactory(esVersion: EsVersion) } } -object RawRorConfigBasedCoreFactory { +object RawRorSettingsBasedCoreFactory { sealed trait CoreCreationError { def reason: Reason @@ -478,7 +478,7 @@ object RawRorConfigBasedCoreFactory { final case class MalformedValue private(value: String) extends Reason object MalformedValue { def fromString(str: String): MalformedValue = MalformedValue(str) - + def apply(json: Json): MalformedValue = from(json) def from(json: Json): MalformedValue = MalformedValue { diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala index 83627f4580..4c11b9650f 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/AuditingSettingsDecoder.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink.Config import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink.Config.{EsDataStreamBasedSink, EsIndexBasedSink, LogBasedSink} import tech.beshu.ror.accesscontrol.domain.RorAuditIndexTemplate.CreationError import tech.beshu.ror.accesscontrol.domain.{AuditCluster, RorAuditDataStream, RorAuditIndexTemplate, RorAuditLoggerName} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{AuditingSettingsCreationError, Reason} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{AuditingSettingsCreationError, Reason} import tech.beshu.ror.accesscontrol.factory.decoders.common.{lemonLabsUriDecoder, nonEmptyStringDecoder} import tech.beshu.ror.accesscontrol.utils.CirceOps.DecodingFailureOps import tech.beshu.ror.accesscontrol.utils.SyncDecoderCreator diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala index f0fe5ec830..9b0075c52c 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala @@ -20,8 +20,8 @@ import io.circe.Decoder import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.optionalDecoder diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/common.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/common.scala index 57f2de6b51..6c334da301 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/common.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/common.scala @@ -32,9 +32,9 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.Json.ResolvableJsonRepresentation import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, ValueLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, ValueLevelCreationError} import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.SyncDecoderCreator import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsBaseDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsBaseDecoder.scala index f97bd373c4..0693201359 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsBaseDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/DefinitionsBaseDecoder.scala @@ -17,8 +17,8 @@ package tech.beshu.ror.accesscontrol.factory.decoders.definitions import cats.Applicative -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions.Item import tech.beshu.ror.accesscontrol.utils.ADecoder import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthenticationServicesDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthenticationServicesDecoder.scala index 8ce212d24d..4c45a78378 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthenticationServicesDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthenticationServicesDecoder.scala @@ -23,9 +23,9 @@ import io.lemonlabs.uri.Url import tech.beshu.ror.accesscontrol.blocks.definitions.* import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.{ADecoder, SyncDecoder, SyncDecoderCreator} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthorizationServicesDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthorizationServicesDecoder.scala index 749331a056..4db45aec40 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthorizationServicesDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ExternalAuthorizationServicesDecoder.scala @@ -24,8 +24,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.HttpExternalAuthorization import tech.beshu.ror.accesscontrol.blocks.definitions.* import tech.beshu.ror.accesscontrol.domain.Header import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, Reason} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, Reason} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.{ADecoder, SyncDecoder, SyncDecoderCreator} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ImpersonationDefinitionsDecoderCreator.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ImpersonationDefinitionsDecoderCreator.scala index a6ab809fd7..11c98029a5 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ImpersonationDefinitionsDecoderCreator.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ImpersonationDefinitionsDecoderCreator.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern import tech.beshu.ror.accesscontrol.domain.UserIdPatterns import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.ruleDecoders import tech.beshu.ror.accesscontrol.utils.CirceOps.{ACursorOps, DecoderHelpers, DecodingFailureOps} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/JwtDefinitionsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/JwtDefinitionsDecoder.scala index e178cb3893..b9d1d7a280 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/JwtDefinitionsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/JwtDefinitionsDecoder.scala @@ -23,9 +23,9 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationSe import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariableCreator import tech.beshu.ror.accesscontrol.domain.{AuthorizationTokenDef, Header, Jwt} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.ExternalAuthenticationServicesDecoder.jwtExternalAuthenticationServiceDecoder import tech.beshu.ror.accesscontrol.utils.CirceOps.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/LdapServicesDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/LdapServicesDecoder.scala index c190d49858..efebc4a653 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/LdapServicesDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/LdapServicesDecoder.scala @@ -36,9 +36,9 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.User import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserGroupsSearchFilterConfig.UserGroupsSearchMode.* import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserSearchFilterConfig.UserIdAttribute import tech.beshu.ror.accesscontrol.domain.PlainTextSecret -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.utils.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ProxyAuthDefinitionsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ProxyAuthDefinitionsDecoder.scala index fa6eae1313..e5076d735a 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ProxyAuthDefinitionsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/ProxyAuthDefinitionsDecoder.scala @@ -20,8 +20,8 @@ import cats.Id import io.circe.Decoder import tech.beshu.ror.accesscontrol.blocks.definitions.ProxyAuth import tech.beshu.ror.accesscontrol.domain.Header -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.{ADecoder, SyncDecoder} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/RorKbnDefinitionsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/RorKbnDefinitionsDecoder.scala index 46de7ac75e..ecadc48d32 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/RorKbnDefinitionsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/RorKbnDefinitionsDecoder.scala @@ -22,9 +22,9 @@ import io.circe.{Decoder, HCursor} import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef.{Name, SignatureCheckMethod} import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariableCreator -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers import tech.beshu.ror.accesscontrol.utils.CirceOps.DecodingFailureOps.fromError import tech.beshu.ror.accesscontrol.utils.CryptoOps.keyStringToPublicKey diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/UsersDefinitionsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/UsersDefinitionsDecoder.scala index 8925882778..979bc430da 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/UsersDefinitionsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/UsersDefinitionsDecoder.scala @@ -34,9 +34,9 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern import tech.beshu.ror.accesscontrol.domain.{Group, GroupIdLike, GroupName, UserIdPatterns} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, ValueLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, ValueLevelCreationError} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.ruleDecoders.{usersDefinitionsAllowedRulesDecoderBy, withUserIdParamsCheck} import tech.beshu.ror.accesscontrol.factory.decoders.rules.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/VariableTransformationAliasesDefinitionsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/VariableTransformationAliasesDefinitionsDecoder.scala index 87b11fca5d..7f36f49f06 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/VariableTransformationAliasesDefinitionsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/definitions/VariableTransformationAliasesDefinitionsDecoder.scala @@ -24,7 +24,7 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.VariableTransformationAli import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler.CompilationError import tech.beshu.ror.accesscontrol.blocks.variables.transformation.domain.{FunctionAlias, FunctionName} import tech.beshu.ror.accesscontrol.blocks.variables.transformation.{SupportedVariablesFunctions, TransformationCompiler} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, Reason} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, Reason} import tech.beshu.ror.accesscontrol.utils.CirceOps.DecodingFailureOps import tech.beshu.ror.accesscontrol.utils.{ADecoder, SyncDecoder, SyncDecoderCreator} import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala index 8828a7a5b2..a799e777fb 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVa import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, GroupsLogic, UserIdPatterns} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.definitions.{Definitions, DefinitionsPack} import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleDecoder import tech.beshu.ror.accesscontrol.factory.decoders.rules.auth.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/RuleBaseDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/RuleBaseDecoder.scala index 0962fed2e8..f7463843ca 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/RuleBaseDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/RuleBaseDecoder.scala @@ -22,8 +22,8 @@ import io.circe.{ACursor, Decoder, HCursor} import tech.beshu.ror.accesscontrol.blocks.Block.RuleDefinition import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.rules.Rule.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleDecoder.DecodingContext import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/AuthKeyRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/AuthKeyRulesDecoders.scala index 6778237903..86163f3fc4 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/AuthKeyRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/AuthKeyRulesDecoders.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyUnixRule.UnixHashed import tech.beshu.ror.accesscontrol.blocks.rules.auth.base.BasicAuthenticationRule import tech.beshu.ror.accesscontrol.domain.{Credentials, PlainTextSecret, User} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.rules.OptionalImpersonatorDefinitionOps import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthenticationRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthenticationRuleDecoder.scala index 8b54d931cf..6cc6dc3235 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthenticationRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthenticationRuleDecoder.scala @@ -23,9 +23,9 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider import tech.beshu.ror.accesscontrol.blocks.rules.auth.ExternalAuthenticationRule import tech.beshu.ror.accesscontrol.blocks.rules.auth.ExternalAuthenticationRule.Settings import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.ExternalAuthenticationServicesDecoder.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.{Definitions, ExternalAuthenticationServicesDecoder} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthorizationRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthorizationRuleDecoder.scala index 900d8cb39b..f8fc3bb7f3 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthorizationRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ExternalAuthorizationRuleDecoder.scala @@ -24,9 +24,9 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider import tech.beshu.ror.accesscontrol.blocks.rules.auth.ExternalAuthorizationRule import tech.beshu.ror.accesscontrol.domain.{GroupsLogic, User} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.definitions.ExternalAuthorizationServicesDecoder.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala index 35d45c592e..0c09da0705 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/JwtAuthRuleDecoder.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.JwtDef import tech.beshu.ror.accesscontrol.blocks.rules.auth.JwtAuthRule import tech.beshu.ror.accesscontrol.blocks.rules.auth.JwtAuthRule.Groups import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.definitions.JwtDefinitionsDecoder.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/LdapRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/LdapRulesDecoders.scala index cacac99013..95f7e57d16 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/LdapRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/LdapRulesDecoders.scala @@ -26,9 +26,9 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule.RuleName import tech.beshu.ror.accesscontrol.blocks.rules.auth.{LdapAuthRule, LdapAuthenticationRule, LdapAuthorizationRule} import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, GroupsLogic} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.LdapServicesDecoder.nameDecoder import tech.beshu.ror.accesscontrol.factory.decoders.definitions.{Definitions, LdapServicesDecoder} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ProxyAuthRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ProxyAuthRuleDecoder.scala index 74cefa954d..68588b805c 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ProxyAuthRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/ProxyAuthRuleDecoder.scala @@ -23,8 +23,8 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider import tech.beshu.ror.accesscontrol.blocks.rules.auth.ProxyAuthRule import tech.beshu.ror.accesscontrol.domain.{Header, User} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common.userIdDecoder import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.definitions.ProxyAuthDefinitionsDecoder.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnAuthRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnAuthRuleDecoder.scala index 575ca8b348..8c11eab9a0 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnAuthRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnAuthRuleDecoder.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthRule.Groups import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthRule import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.definitions.RorKbnDefinitionsDecoder.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/BaseGroupsRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/BaseGroupsRuleDecoder.scala index 5a0b4dc4e8..9fc3fb2d4b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/BaseGroupsRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/BaseGroupsRuleDecoder.scala @@ -30,8 +30,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.auth.base.BaseGroupsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableGroupsLogic, RuntimeResolvableVariableCreator} import tech.beshu.ror.accesscontrol.domain.GroupsLogic.{NegativeGroupsLogic, PositiveGroupsLogic} import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, GroupIdLike, GroupsLogic} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.rules.auth.groups.BaseGroupsRuleDecoder.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsLogicRepresentationDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsLogicRepresentationDecoder.scala index 098c963ba3..f192bb575a 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsLogicRepresentationDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsLogicRepresentationDecoder.scala @@ -21,8 +21,8 @@ import io.circe.{ACursor, Decoder, FailedCursor} import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.rules.Rule.RuleName import tech.beshu.ror.accesscontrol.blocks.rules.auth.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.auth.groups.GroupsLogicRepresentationDecoder.GroupsLogicDecodingResult import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.{SyncDecoder, SyncDecoderCreator} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsRuleDecoder.scala index 97885fd181..35e2630693 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/groups/GroupsRuleDecoder.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.auth.base.BaseGroupsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariableCreator import tech.beshu.ror.accesscontrol.domain.GroupsLogic import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleDecoder diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/DataStreamsRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/DataStreamsRuleDecoder.scala index 4242e272a3..f533a3d960 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/DataStreamsRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/DataStreamsRuleDecoder.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator} import tech.beshu.ror.accesscontrol.domain.DataStreamName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.elasticsearch.DataStreamsDecodersHelper.* import tech.beshu.ror.accesscontrol.orders.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/FieldsRuleLikeDecoderHelperBase.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/FieldsRuleLikeDecoderHelperBase.scala index f9c24098ac..756167525b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/FieldsRuleLikeDecoderHelperBase.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/FieldsRuleLikeDecoderHelperBase.scala @@ -20,9 +20,9 @@ import eu.timepit.refined.types.string.NonEmptyString import io.circe.Decoder import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariableCreator -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/IndicesRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/IndicesRulesDecoders.scala index 7d8b512436..e26ce05857 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/IndicesRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/IndicesRulesDecoders.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator} import tech.beshu.ror.accesscontrol.domain.ClusterIndexName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.elasticsearch.IndicesDecodersHelper.* import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/RepositoriesRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/RepositoriesRuleDecoder.scala index a4a0fa9861..bbe89fac5b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/RepositoriesRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/RepositoriesRuleDecoder.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator} import tech.beshu.ror.accesscontrol.domain.RepositoryName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.elasticsearch.RepositoriesDecodersHelper.* import tech.beshu.ror.accesscontrol.orders.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/SnapshotsRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/SnapshotsRuleDecoder.scala index 3dd249c1cd..636865bd36 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/SnapshotsRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/elasticsearch/SnapshotsRuleDecoder.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator} import tech.beshu.ror.accesscontrol.domain.SnapshotName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.elasticsearch.SnapshotDecodersHelper.* import tech.beshu.ror.accesscontrol.orders.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MaxBodyLengthRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MaxBodyLengthRuleDecoder.scala index 2bf2070ae0..cf1109bb62 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MaxBodyLengthRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MaxBodyLengthRuleDecoder.scala @@ -21,8 +21,8 @@ import squants.information.Bytes import tech.beshu.ror.accesscontrol.blocks.Block.RuleDefinition import tech.beshu.ror.accesscontrol.blocks.rules.http.MaxBodyLengthRule import tech.beshu.ror.accesscontrol.blocks.rules.http.MaxBodyLengthRule.Settings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderOps import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MethodsRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MethodsRuleDecoder.scala index fb188d90d2..f582a60022 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MethodsRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/MethodsRuleDecoder.scala @@ -20,8 +20,8 @@ import io.circe.Decoder import tech.beshu.ror.accesscontrol.blocks.Block.RuleDefinition import tech.beshu.ror.accesscontrol.blocks.rules.http.MethodsRule import tech.beshu.ror.accesscontrol.blocks.rules.http.MethodsRule.Settings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.factory.decoders.rules.http.MethodsRuleDecoderHelper.methodDecoder import tech.beshu.ror.accesscontrol.orders.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/SessionMaxIdleRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/SessionMaxIdleRuleDecoder.scala index 36b00882d3..bb3d3ffe39 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/SessionMaxIdleRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/SessionMaxIdleRuleDecoder.scala @@ -21,7 +21,7 @@ import tech.beshu.ror.accesscontrol.blocks.Block.RuleDefinition import tech.beshu.ror.accesscontrol.blocks.rules.http.SessionMaxIdleRule import tech.beshu.ror.accesscontrol.blocks.rules.http.SessionMaxIdleRule.Settings import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.common import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.utils.CirceOps.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/UriRegexRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/UriRegexRuleDecoder.scala index dc23a579bf..57dad83c31 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/UriRegexRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/http/UriRegexRuleDecoder.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.http.UriRegexRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariable.Convertible.ConvertError import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.orders.patternOrder import tech.beshu.ror.accesscontrol.utils.CirceOps.{DecoderHelpers, DecoderOps} diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala index 9774214adc..510731b2b2 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala @@ -27,9 +27,9 @@ import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.Json.ResolvableJsonRepresentation import tech.beshu.ror.accesscontrol.domain.KibanaAllowedApiPath.* import tech.beshu.ror.accesscontrol.domain.KibanaAllowedApiPath.AllowedHttpMethod.HttpMethod -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{RulesLevelCreationError, ValueLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{RulesLevelCreationError, ValueLevelCreationError} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields import tech.beshu.ror.accesscontrol.utils.CirceOps.* diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/ADecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/ADecoder.scala index 5f8e104692..34500a3f48 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/ADecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/ADecoder.scala @@ -20,8 +20,8 @@ import cats.implicits.* import cats.{Functor, Id} import io.circe.* import monix.eval.Task -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.utils.yaml.YamlOps diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/CirceOps.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/CirceOps.scala index d7d2d53c4e..b8b49cd950 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/CirceOps.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/utils/CirceOps.scala @@ -27,9 +27,9 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVa import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeResolvableVariableCreator.CreationError import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeSingleResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableVariableCreator, RuntimeSingleResolvableVariable} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{Reason, ValueLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{Reason, ValueLevelCreationError} import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.FieldListResult.* import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index 5af9e763e8..d6144ebe0b 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvid import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RequestId, User} import tech.beshu.ror.accesscontrol.factory.RorDependencies -import tech.beshu.ror.boot.RorInstance.{IndexConfigUpdateError, TestConfig} +import tech.beshu.ror.boot.RorInstance.{IndexSettingsUpdateError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.CirceErrorOps @@ -111,12 +111,12 @@ class AuthMockApi(rorInstance: RorInstance) onNotSet: String => A, onInvalidated: String => A) (implicit requestId: RequestId): Task[Either[A, B]] = { - rorInstance.currentTestConfig().map { - case TestConfig.NotSet => + rorInstance.currentTestSettings().map { + case TestSettings.NotSet => Left(onNotSet(testSettingsNotConfiguredMessage)) - case TestConfig.Present(_, dependencies, _, _) => + case TestSettings.Present(_, dependencies, _, _) => Right(action(dependencies.services)) - case _:TestConfig.Invalidated => + case _:TestSettings.Invalidated => Left(onInvalidated(testSettingsInvalidatedMessage)) } } @@ -157,11 +157,11 @@ class AuthMockApi(rorInstance: RorInstance) .map { case Right(()) => Right(UpdateAuthMock.Success("Auth mock updated")) - case Left(IndexConfigUpdateError.TestSettingsNotSet) => + case Left(IndexSettingsUpdateError.TestSettingsNotSet) => Left(AuthMockResponse.UpdateAuthMock.NotConfigured(testSettingsNotConfiguredMessage)) - case Left(IndexConfigUpdateError.TestSettingsInvalidated) => + case Left(IndexSettingsUpdateError.TestSettingsInvalidated) => Left(AuthMockResponse.UpdateAuthMock.Invalidated(testSettingsInvalidatedMessage)) - case Left(IndexConfigUpdateError.IndexConfigSavingError(error)) => + case Left(IndexSettingsUpdateError.IndexSettingsSavingError(error)) => Left(AuthMockResponse.UpdateAuthMock.Failed(s"Cannot save auth services mocks: ${error.show}")) } } diff --git a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala deleted file mode 100644 index 4efbbba86d..0000000000 --- a/core/src/main/scala/tech/beshu/ror/api/ConfigApi.scala +++ /dev/null @@ -1,210 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.api - -import cats.Show -import cats.data.EitherT -import cats.implicits.* -import io.circe.Decoder -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.* -import tech.beshu.ror.api.ConfigApi.ConfigRequest.Type -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} -import tech.beshu.ror.boot.RorInstance.{IndexConfigReloadError, RawConfigReloadError} -import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.FileRorSettingsLoader -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.utils.CirceOps.toCirceErrorOps - -class ConfigApi(rorInstance: RorInstance, - rawRorConfigYamlParser: RawRorSettingsYamlParser, - indexConfigManager: IndexSettingsManager[RawRorSettings], - fileConfigLoader: FileRorSettingsLoader) - extends Logging { - - import ConfigApi.Utils.* - import ConfigApi.Utils.decoders.* - - def call(request: ConfigRequest) - (implicit requestId: RequestId): Task[ConfigResponse] = { - val configResponse = request.aType match { - case Type.ForceReload => forceReloadRor() - case Type.ProvideIndexConfig => provideRorIndexConfig() - case Type.ProvideFileConfig => provideRorFileConfig() - case Type.UpdateIndexConfig => updateIndexConfiguration(request.body) - } - configResponse - .executeOn(RorSchedulers.restApiScheduler) - } - - private def forceReloadRor() - (implicit requestId: RequestId): Task[ConfigResponse] = { - rorInstance - .forceReloadFromIndex() - .map { - case Right(_) => - ForceReloadConfig.Success("ReadonlyREST settings were reloaded with success!") - case Left(IndexConfigReloadError.LoadingConfigError(error)) => - ForceReloadConfig.Failure(error.show) - case Left(IndexConfigReloadError.ReloadError(RawConfigReloadError.ConfigUpToDate(_))) => - ForceReloadConfig.Failure("Current settings are already loaded") - case Left(IndexConfigReloadError.ReloadError(RawConfigReloadError.RorInstanceStopped)) => - ForceReloadConfig.Failure("ROR is stopped") - case Left(IndexConfigReloadError.ReloadError(RawConfigReloadError.ReloadingFailed(failure))) => - ForceReloadConfig.Failure(s"Cannot reload new settings: ${failure.message.show}") - } - } - - private def updateIndexConfiguration(body: String) - (implicit requestId: RequestId): Task[ConfigResponse] = { - val result = for { - updateRequest <- EitherT.fromEither[Task](decodeUpdateRequest(body)) - config <- rorConfigFrom(updateRequest.configString) - _ <- forceReloadAndSaveNewConfig(config) - } yield UpdateIndexConfig.Success("updated settings") - - result.value.map(_.merge) - } - - private def provideRorFileConfig(): Task[ConfigResponse] = { - fileConfigLoader - .load() - .map { - case Right(config) => ProvideFileConfig.Config(config.raw) - case Left(error) => ProvideFileConfig.Failure(error.show) - } - } - - private def provideRorIndexConfig(): Task[ConfigResponse] = { - indexConfigManager - .load() - .map { - case Right(config) => - ProvideIndexConfig.Config(config.raw) - case Left(SpecializedError(error: LoadingIndexSettingsError.IndexNotExist.type)) => - ProvideIndexConfig.ConfigNotFound(Show[LoadingIndexSettingsError].show(error)) - case Left(error) => - ProvideIndexConfig.Failure(error.show) - } - } - - private def decodeUpdateRequest(payload: String): Either[ConfigResponse.Failure, UpdateConfigRequest] = { - io.circe.parser.decode[UpdateConfigRequest](payload) - .left.map(error => ConfigResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage.show}]")) - } - - private def rorConfigFrom(configString: String): EitherT[Task, ConfigResponse, RawRorSettings] = EitherT { - rawRorConfigYamlParser - .fromString(configString) - .map(_.left.map(error => UpdateIndexConfig.Failure(error.show))) - } - - private def forceReloadAndSaveNewConfig(config: RawRorSettings) - (implicit requestId: RequestId): EitherT[Task, ConfigResponse, Unit] = { - EitherT(rorInstance.forceReloadAndSave(config)) - .leftMap { - case IndexConfigSavingError(error) => - UpdateIndexConfig.Failure(s"Cannot save new settings: ${error.show}") - case ReloadError(RawConfigReloadError.ConfigUpToDate(_)) => - UpdateIndexConfig.Failure(s"Current settings are already loaded") - case ReloadError(RawConfigReloadError.RorInstanceStopped) => - UpdateIndexConfig.Failure(s"ROR instance is being stopped") - case ReloadError(RawConfigReloadError.ReloadingFailed(failure)) => - UpdateIndexConfig.Failure(s"Cannot reload new settings: ${failure.message.show}") - } - } -} - -object ConfigApi { - - final case class ConfigRequest(aType: ConfigRequest.Type, - body: String) - object ConfigRequest { - sealed trait Type - object Type { - case object ForceReload extends Type - case object ProvideIndexConfig extends Type - case object ProvideFileConfig extends Type - case object UpdateIndexConfig extends Type - } - } - - sealed trait ConfigResponse - object ConfigResponse { - sealed trait ForceReloadConfig extends ConfigResponse - object ForceReloadConfig { - final case class Success(message: String) extends ForceReloadConfig - final case class Failure(message: String) extends ForceReloadConfig - } - - sealed trait ProvideIndexConfig extends ConfigResponse - object ProvideIndexConfig { - final case class Config(rawConfig: String) extends ProvideIndexConfig - final case class ConfigNotFound(message: String) extends ProvideIndexConfig - final case class Failure(message: String) extends ProvideIndexConfig - } - - sealed trait ProvideFileConfig extends ConfigResponse - object ProvideFileConfig { - final case class Config(rawConfig: String) extends ProvideFileConfig - final case class Failure(message: String) extends ProvideFileConfig - } - - sealed trait UpdateIndexConfig extends ConfigResponse - object UpdateIndexConfig { - final case class Success(message: String) extends UpdateIndexConfig - final case class Failure(message: String) extends UpdateIndexConfig - } - - sealed trait Failure extends ConfigResponse - object Failure { - final case class BadRequest(message: String) extends Failure - } - } - - implicit class StatusFromConfigResponse(val response: ConfigResponse) extends AnyVal { - def status: String = response match { - case _: ForceReloadConfig.Success => "ok" - case _: ForceReloadConfig.Failure => "ko" - case _: ProvideIndexConfig.Config => "ok" - case _: ProvideIndexConfig.ConfigNotFound => "empty" - case _: ProvideIndexConfig.Failure => "ko" - case _: ProvideFileConfig.Config => "ok" - case _: ProvideFileConfig.Failure => "ko" - case _: UpdateIndexConfig.Success => "ok" - case _: UpdateIndexConfig.Failure => "ko" - case failure: ConfigResponse.Failure => failure match { - case Failure.BadRequest(_) => "ko" - } - } - } - - private object Utils { - final case class UpdateConfigRequest(configString: String) - - object decoders { - implicit val updateConfigRequestDecoder: Decoder[UpdateConfigRequest] = - Decoder.forProduct1("settings")(UpdateConfigRequest.apply) - } - } -} diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala new file mode 100644 index 0000000000..8a3d5fedf0 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -0,0 +1,206 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.api + +import cats.Show +import cats.data.EitherT +import cats.implicits.* +import io.circe.Decoder +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.MainRorSettingsApi.* +import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsRequest.Type +import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} +import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} +import tech.beshu.ror.boot.{RorInstance, RorSchedulers} +import tech.beshu.ror.configuration.loader.RorMainSettingsManager +import tech.beshu.ror.configuration.loader.SettingsManager.LoadingFromIndexError +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.utils.CirceOps.toCirceErrorOps + +class MainRorSettingsApi(rorInstance: RorInstance, + settingsYamlParser: RawRorSettingsYamlParser, + settingsManager: RorMainSettingsManager) + extends Logging { + + import MainRorSettingsApi.Utils.* + import MainRorSettingsApi.Utils.decoders.* + + def call(request: MainSettingsRequest) + (implicit requestId: RequestId): Task[MainSettingsResponse] = { + val settingsResponse = request.aType match { + case Type.ForceReload => forceReloadRor() + case Type.ProvideIndexSettings => provideRorIndexSettings() + case Type.ProvideFileSettings => provideRorFileSettings() + case Type.UpdateIndexSettings => updateRorIndexSettings(request.body) + } + settingsResponse + .executeOn(RorSchedulers.restApiScheduler) + } + + private def forceReloadRor() + (implicit requestId: RequestId): Task[MainSettingsResponse] = { + rorInstance + .forceReloadFromIndex() + .map { + case Right(_) => + ForceReloadMainSettings.Success("ReadonlyREST settings were reloaded with success!") + case Left(IndexSettingsReloadError.LoadingSettingsError(error)) => + ForceReloadMainSettings.Failure(error.show) + case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))) => + ForceReloadMainSettings.Failure("Current settings are already loaded") + case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)) => + ForceReloadMainSettings.Failure("ROR is stopped") + case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(failure))) => + ForceReloadMainSettings.Failure(s"Cannot reload new settings: ${failure.message.show}") + } + } + + private def updateRorIndexSettings(body: String) + (implicit requestId: RequestId): Task[MainSettingsResponse] = { + val result = for { + updateRequest <- EitherT.fromEither[Task](decodeUpdateRequest(body)) + newRorSettings <- rorMainSettingsFrom(updateRequest.settingsString) + _ <- forceReloadAndSaveNewSettings(newRorSettings) + } yield UpdateIndexMainSettings.Success("updated settings") + + result.value.map(_.merge) + } + + private def provideRorFileSettings(): Task[MainSettingsResponse] = { + settingsManager + .loadFromFile(???) + .map { + case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) + case Left(error) => ProvideFileMainSettings.Failure(error.show) + } + } + + private def provideRorIndexSettings(): Task[MainSettingsResponse] = { + settingsManager + .loadFromIndex() + .map { + case Right(settings) => + ProvideIndexMainSettings.MainSettings(settings.raw) + case Left(error@LoadingFromIndexError.IndexNotExist) => + ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) + case Left(error) => ProvideIndexMainSettings.Failure(error.show) + } + } + + private def decodeUpdateRequest(payload: String): Either[MainSettingsResponse.Failure, UpdateSettingsRequest] = { + io.circe.parser.decode[UpdateSettingsRequest](payload) + .left.map(error => MainSettingsResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage.show}]")) + } + + private def rorMainSettingsFrom(settingsString: String): EitherT[Task, MainSettingsResponse, RawRorSettings] = EitherT { + settingsYamlParser + .fromString(settingsString) + .map(_.left.map(error => UpdateIndexMainSettings.Failure(error.show))) + } + + private def forceReloadAndSaveNewSettings(settings: RawRorSettings) + (implicit requestId: RequestId): EitherT[Task, MainSettingsResponse, Unit] = { + EitherT(rorInstance.forceReloadAndSave(settings)) + .leftMap { + case IndexSettingsSavingError(error) => + UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") + case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => + UpdateIndexMainSettings.Failure(s"Current settings are already loaded") + case ReloadError(RawSettingsReloadError.RorInstanceStopped) => + UpdateIndexMainSettings.Failure(s"ROR instance is being stopped") + case ReloadError(RawSettingsReloadError.ReloadingFailed(failure)) => + UpdateIndexMainSettings.Failure(s"Cannot reload new settings: ${failure.message.show}") + } + } +} + +object MainRorSettingsApi { + + final case class MainSettingsRequest(aType: MainSettingsRequest.Type, + body: String) + object MainSettingsRequest { + sealed trait Type + object Type { + case object ForceReload extends Type + case object ProvideIndexSettings extends Type + case object ProvideFileSettings extends Type + case object UpdateIndexSettings extends Type + } + } + + sealed trait MainSettingsResponse + object MainSettingsResponse { + sealed trait ForceReloadMainSettings extends MainSettingsResponse + object ForceReloadMainSettings { + final case class Success(message: String) extends ForceReloadMainSettings + final case class Failure(message: String) extends ForceReloadMainSettings + } + + sealed trait ProvideIndexMainSettings extends MainSettingsResponse + object ProvideIndexMainSettings { + final case class MainSettings(rawSettings: String) extends ProvideIndexMainSettings + final case class MainSettingsNotFound(message: String) extends ProvideIndexMainSettings + final case class Failure(message: String) extends ProvideIndexMainSettings + } + + sealed trait ProvideFileMainSettings extends MainSettingsResponse + object ProvideFileMainSettings { + final case class MainSettings(rawSettings: String) extends ProvideFileMainSettings + final case class Failure(message: String) extends ProvideFileMainSettings + } + + sealed trait UpdateIndexMainSettings extends MainSettingsResponse + object UpdateIndexMainSettings { + final case class Success(message: String) extends UpdateIndexMainSettings + final case class Failure(message: String) extends UpdateIndexMainSettings + } + + sealed trait Failure extends MainSettingsResponse + object Failure { + final case class BadRequest(message: String) extends Failure + } + } + + implicit class StatusFromSettingsResponse(val response: MainSettingsResponse) extends AnyVal { + def status: String = response match { + case _: ForceReloadMainSettings.Success => "ok" + case _: ForceReloadMainSettings.Failure => "ko" + case _: ProvideIndexMainSettings.MainSettings => "ok" + case _: ProvideIndexMainSettings.MainSettingsNotFound => "empty" + case _: ProvideIndexMainSettings.Failure => "ko" + case _: ProvideFileMainSettings.MainSettings => "ok" + case _: ProvideFileMainSettings.Failure => "ko" + case _: UpdateIndexMainSettings.Success => "ok" + case _: UpdateIndexMainSettings.Failure => "ko" + case failure: MainSettingsResponse.Failure => failure match { + case Failure.BadRequest(_) => "ko" + } + } + } + + private object Utils { + final case class UpdateSettingsRequest(settingsString: String) + + object decoders { + implicit val updateSettingsRequestDecoder: Decoder[UpdateSettingsRequest] = + Decoder.forProduct1("settings")(UpdateSettingsRequest.apply) + } + } +} diff --git a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala deleted file mode 100644 index 329990e4e9..0000000000 --- a/core/src/main/scala/tech/beshu/ror/api/TestConfigApi.scala +++ /dev/null @@ -1,267 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.api - -import cats.data.EitherT -import cats.implicits.* -import io.circe.Decoder -import monix.eval.Task -import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning -import tech.beshu.ror.accesscontrol.domain.{LoggedUser, RequestId} -import tech.beshu.ror.api.TestConfigApi.TestConfigRequest.Type -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* -import tech.beshu.ror.api.TestConfigApi.{TestConfigRequest, TestConfigResponse} -import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} -import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, RawConfigReloadError, TestConfig} -import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.syntax.* -import tech.beshu.ror.utils.CirceOps.toCirceErrorOps -import tech.beshu.ror.utils.DurationOps.* - -import java.time.Instant -import scala.concurrent.duration.* -import scala.util.Try - -class TestConfigApi(rorInstance: RorInstance, - rawRorConfigYamlParser: RawRorSettingsYamlParser) { - - import tech.beshu.ror.api.TestConfigApi.Utils.* - import tech.beshu.ror.api.TestConfigApi.Utils.decoders.* - - def call(request: RorApiRequest[TestConfigRequest]) - (implicit requestId: RequestId): Task[TestConfigResponse] = { - val testConfigResponse = request.request.aType match { - case Type.ProvideTestConfig => loadCurrentTestConfig() - case Type.UpdateTestConfig => updateTestConfig(request.request.body) - case Type.InvalidateTestConfig => invalidateTestConfig() - case Type.ProvideLocalUsers => provideLocalUsers(request.loggedUser) - } - testConfigResponse - .executeOn(RorSchedulers.restApiScheduler) - } - - private def updateTestConfig(body: String) - (implicit requestId: RequestId): Task[TestConfigResponse] = { - val result = for { - updateRequest <- EitherT.fromEither[Task](decodeUpdateConfigRequest(body)) - rorConfig <- rorTestConfig(updateRequest.configString) - response <- forceReloadTestConfig(rorConfig, updateRequest.ttl) - } yield response - - result.value.map(_.merge) - } - - private def decodeUpdateConfigRequest(payload: String): Either[Failure, UpdateTestConfigRequest] = { - io.circe.parser.decode[UpdateTestConfigRequest](payload) - .left.map(error => TestConfigResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage}]")) - } - - private def rorTestConfig(configString: String): EitherT[Task, TestConfigResponse, RawRorSettings] = EitherT { - rawRorConfigYamlParser - .fromString(configString) - .map(_.left.map(error => TestConfigResponse.UpdateTestConfig.FailedResponse(error.show))) - } - - private def invalidateTestConfig() - (implicit requestId: RequestId): Task[TestConfigResponse] = { - rorInstance - .invalidateTestConfigEngine() - .map { - case Right(()) => - TestConfigResponse.InvalidateTestConfig.SuccessResponse("ROR Test settings are invalidated") - case Left(IndexConfigInvalidationError.IndexConfigSavingError(error)) => - TestConfigResponse.InvalidateTestConfig.FailedResponse(s"Cannot invalidate test settings: ${error.show}") - } - } - - private def loadCurrentTestConfig() - (implicit requestId: RequestId): Task[TestConfigResponse] = { - rorInstance - .currentTestConfig() - .map { - case TestConfig.NotSet => - TestConfigResponse.ProvideTestConfig.TestSettingsNotConfigured("ROR Test settings are not configured") - case TestConfig.Present(rawConfig, dependencies, configuredTtl, validTo) => - TestConfigResponse.ProvideTestConfig.CurrentTestSettings( - ttl = apiFormat(configuredTtl), - validTo = validTo, - settings = rawConfig, - warnings = dependencies.impersonationWarningsReader.read().map(toWarningDto) - ) - case TestConfig.Invalidated(recentConfig, ttl) => - TestConfigResponse.ProvideTestConfig.TestSettingsInvalidated("ROR Test settings are invalidated", recentConfig, apiFormat(ttl)) - } - } - - private def provideLocalUsers(loggedUser: Option[LoggedUser]) - (implicit requestId: RequestId): Task[TestConfigResponse] = { - rorInstance - .currentTestConfig() - .map { - case TestConfig.NotSet => - TestConfigResponse.ProvideLocalUsers.TestSettingsNotConfigured("ROR Test settings are not configured") - case TestConfig.Present(_, dependencies, _, _) => - val filteredLocalUsers = dependencies.localUsers.users -- loggedUser.map(_.id) - TestConfigResponse.ProvideLocalUsers.SuccessResponse( - users = filteredLocalUsers.map(_.value.value).toList, - unknownUsers = dependencies.localUsers.unknownUsers - ) - case _:TestConfig.Invalidated => - TestConfigResponse.ProvideLocalUsers.TestSettingsInvalidated("ROR Test settings are invalidated") - } - } - - private def forceReloadTestConfig(config: RawRorSettings, - ttl: PositiveFiniteDuration) - (implicit requestId: RequestId): EitherT[Task, TestConfigResponse, TestConfigResponse] = { - EitherT( - rorInstance - .forceReloadTestConfigEngine(config, ttl) - .map { - _ - .map { newTestConfig => - TestConfigResponse.UpdateTestConfig.SuccessResponse( - message = "updated settings", - validTo = newTestConfig.validTo, - warnings = newTestConfig.dependencies.impersonationWarningsReader.read().map(toWarningDto) - ) - } - .leftMap { - case IndexConfigSavingError(error) => - TestConfigResponse.UpdateTestConfig.FailedResponse(s"Cannot reload new settings: ${error.show}") - case ReloadError(RawConfigReloadError.ConfigUpToDate(_)) => - TestConfigResponse.UpdateTestConfig.FailedResponse(s"Current settings are already loaded") - case ReloadError(RawConfigReloadError.RorInstanceStopped) => - TestConfigResponse.UpdateTestConfig.FailedResponse(s"ROR instance is being stopped") - case ReloadError(RawConfigReloadError.ReloadingFailed(failure)) => - TestConfigResponse.UpdateTestConfig.FailedResponse(s"Cannot reload new settings: ${failure.message}") - } - } - ) - } - - private def toWarningDto(warning: ImpersonationWarning): TestConfigResponse.Warning = { - TestConfigResponse.Warning( - blockName = warning.block.value, - ruleName = warning.ruleName.value, - message = warning.message.value, - hint = warning.hint - ) - } -} - -object TestConfigApi { - - final case class TestConfigRequest(aType: TestConfigRequest.Type, - body: String) - - object TestConfigRequest { - sealed trait Type - object Type { - case object ProvideTestConfig extends Type - case object UpdateTestConfig extends Type - case object InvalidateTestConfig extends Type - case object ProvideLocalUsers extends Type - } - } - - sealed trait TestConfigResponse - object TestConfigResponse { - - final case class Warning(blockName: String, - ruleName: String, - message: String, - hint: String) - - sealed trait ProvideTestConfig extends TestConfigResponse - object ProvideTestConfig { - final case class CurrentTestSettings(ttl: FiniteDuration, - validTo: Instant, - settings: RawRorSettings, - warnings: List[Warning]) extends ProvideTestConfig - - final case class TestSettingsNotConfigured(message: String) extends ProvideTestConfig - final case class TestSettingsInvalidated(message: String, - settings: RawRorSettings, - ttl: FiniteDuration) extends ProvideTestConfig - } - - sealed trait UpdateTestConfig extends TestConfigResponse - object UpdateTestConfig { - final case class SuccessResponse(message: String, validTo: Instant, warnings: List[Warning]) extends UpdateTestConfig - final case class FailedResponse(message: String) extends UpdateTestConfig - } - - sealed trait InvalidateTestConfig extends TestConfigResponse - object InvalidateTestConfig { - final case class SuccessResponse(message: String) extends InvalidateTestConfig - final case class FailedResponse(message: String) extends InvalidateTestConfig - } - - sealed trait ProvideLocalUsers extends TestConfigResponse - object ProvideLocalUsers { - final case class SuccessResponse(users: List[String], unknownUsers: Boolean) extends ProvideLocalUsers - final case class TestSettingsNotConfigured(message: String) extends ProvideLocalUsers - final case class TestSettingsInvalidated(message: String) extends ProvideLocalUsers - } - - sealed trait Failure extends TestConfigResponse - object Failure { - final case class BadRequest(message: String) extends Failure - } - } - - implicit class StatusFromTestConfigResponse(val response: TestConfigResponse) extends AnyVal { - def status: String = response match { - case _: ProvideTestConfig.CurrentTestSettings => "TEST_SETTINGS_PRESENT" - case _: ProvideTestConfig.TestSettingsNotConfigured => "TEST_SETTINGS_NOT_CONFIGURED" - case _: ProvideTestConfig.TestSettingsInvalidated => "TEST_SETTINGS_INVALIDATED" - case _: UpdateTestConfig.SuccessResponse => "OK" - case _: UpdateTestConfig.FailedResponse => "FAILED" - case _: InvalidateTestConfig.SuccessResponse => "OK" - case _: InvalidateTestConfig.FailedResponse => "FAILED" - case _: ProvideLocalUsers.SuccessResponse => "OK" - case _: ProvideLocalUsers.TestSettingsNotConfigured => "TEST_SETTINGS_NOT_CONFIGURED" - case _: ProvideLocalUsers.TestSettingsInvalidated => "TEST_SETTINGS_INVALIDATED" - case _: Failure.BadRequest => "FAILED" - } - } - - private object Utils { - final case class UpdateTestConfigRequest(configString: String, - ttl: PositiveFiniteDuration) - - private def parseDuration(value: String): Either[String, PositiveFiniteDuration] = { - Try(Duration(value)) - .toEither - .leftMap(_ =>s"Cannot parse '${value.show}' as duration.") - .flatMap(_.toRefinedPositive) - } - - object decoders { - implicit val durationDecoder: Decoder[PositiveFiniteDuration] = Decoder.decodeString.emap(parseDuration) - - implicit val updateTestConfigRequestDecoder: Decoder[UpdateTestConfigRequest] = - Decoder.forProduct2("settings", "ttl")(UpdateTestConfigRequest.apply) - } - - def apiFormat(duration: PositiveFiniteDuration): FiniteDuration = { - duration.value.toCoarsest - } - } -} diff --git a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala new file mode 100644 index 0000000000..9a3b0969e9 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala @@ -0,0 +1,267 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.api + +import cats.data.EitherT +import cats.implicits.* +import io.circe.Decoder +import monix.eval.Task +import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning +import tech.beshu.ror.accesscontrol.domain.{LoggedUser, RequestId} +import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsRequest.Type +import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse.* +import tech.beshu.ror.api.TestRorSettingsApi.{TestSettingsRequest, TestSettingsResponse} +import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} +import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, RawSettingsReloadError, TestSettings} +import tech.beshu.ror.boot.{RorInstance, RorSchedulers} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.syntax.* +import tech.beshu.ror.utils.CirceOps.toCirceErrorOps +import tech.beshu.ror.utils.DurationOps.* + +import java.time.Instant +import scala.concurrent.duration.* +import scala.util.Try + +class TestRorSettingsApi(rorInstance: RorInstance, + settingsYamlParser: RawRorSettingsYamlParser) { + + import tech.beshu.ror.api.TestRorSettingsApi.Utils.* + import tech.beshu.ror.api.TestRorSettingsApi.Utils.decoders.* + + def call(request: RorApiRequest[TestSettingsRequest]) + (implicit requestId: RequestId): Task[TestSettingsResponse] = { + val testSettingsResponse = request.request.aType match { + case Type.ProvideTestSettings => loadCurrentTestSettings() + case Type.UpdateTestSettings => updateTestSettings(request.request.body) + case Type.InvalidateTestSettings => invalidateTestSettings() + case Type.ProvideLocalUsers => provideLocalUsers(request.loggedUser) + } + testSettingsResponse + .executeOn(RorSchedulers.restApiScheduler) + } + + private def updateTestSettings(body: String) + (implicit requestId: RequestId): Task[TestSettingsResponse] = { + val result = for { + updateRequest <- EitherT.fromEither[Task](decodeUpdateSettingsRequest(body)) + rorSettings <- rorTestSettingsFrom(updateRequest.settingsString) + response <- forceReloadTestSettings(rorSettings, updateRequest.ttl) + } yield response + + result.value.map(_.merge) + } + + private def decodeUpdateSettingsRequest(payload: String): Either[Failure, UpdateTestSettingsRequest] = { + io.circe.parser.decode[UpdateTestSettingsRequest](payload) + .left.map(error => TestSettingsResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage}]")) + } + + private def rorTestSettingsFrom(settingsString: String): EitherT[Task, TestSettingsResponse, RawRorSettings] = EitherT { + settingsYamlParser + .fromString(settingsString) + .map(_.left.map(error => TestSettingsResponse.UpdateTestSettings.FailedResponse(error.show))) + } + + private def invalidateTestSettings() + (implicit requestId: RequestId): Task[TestSettingsResponse] = { + rorInstance + .invalidateTestSettingsEngine() + .map { + case Right(()) => + TestSettingsResponse.InvalidateTestSettings.SuccessResponse("ROR Test settings are invalidated") + case Left(IndexSettingsInvalidationError.IndexSettingsSavingError(error)) => + TestSettingsResponse.InvalidateTestSettings.FailedResponse(s"Cannot invalidate test settings: ${error.show}") + } + } + + private def loadCurrentTestSettings() + (implicit requestId: RequestId): Task[TestSettingsResponse] = { + rorInstance + .currentTestSettings() + .map { + case TestSettings.NotSet => + TestSettingsResponse.ProvideTestSettings.TestSettingsNotConfigured("ROR Test settings are not configured") + case TestSettings.Present(rawSettings, dependencies, configuredTtl, validTo) => + TestSettingsResponse.ProvideTestSettings.CurrentTestSettings( + ttl = apiFormat(configuredTtl), + validTo = validTo, + settings = rawSettings, + warnings = dependencies.impersonationWarningsReader.read().map(toWarningDto) + ) + case TestSettings.Invalidated(recentConfig, ttl) => + TestSettingsResponse.ProvideTestSettings.TestSettingsInvalidated("ROR Test settings are invalidated", recentConfig, apiFormat(ttl)) + } + } + + private def provideLocalUsers(loggedUser: Option[LoggedUser]) + (implicit requestId: RequestId): Task[TestSettingsResponse] = { + rorInstance + .currentTestSettings() + .map { + case TestSettings.NotSet => + TestSettingsResponse.ProvideLocalUsers.TestSettingsNotConfigured("ROR Test settings are not configured") + case TestSettings.Present(_, dependencies, _, _) => + val filteredLocalUsers = dependencies.localUsers.users -- loggedUser.map(_.id) + TestSettingsResponse.ProvideLocalUsers.SuccessResponse( + users = filteredLocalUsers.map(_.value.value).toList, + unknownUsers = dependencies.localUsers.unknownUsers + ) + case _: TestSettings.Invalidated => + TestSettingsResponse.ProvideLocalUsers.TestSettingsInvalidated("ROR Test settings are invalidated") + } + } + + private def forceReloadTestSettings(settings: RawRorSettings, + ttl: PositiveFiniteDuration) + (implicit requestId: RequestId): EitherT[Task, TestSettingsResponse, TestSettingsResponse] = { + EitherT( + rorInstance + .forceReloadTestSettingsEngine(settings, ttl) + .map { + _ + .map { newTestSettings => + TestSettingsResponse.UpdateTestSettings.SuccessResponse( + message = "updated settings", + validTo = newTestSettings.validTo, + warnings = newTestSettings.dependencies.impersonationWarningsReader.read().map(toWarningDto) + ) + } + .leftMap { + case IndexSettingsSavingError(error) => + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ${error.show}") + case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Current settings are already loaded") + case ReloadError(RawSettingsReloadError.RorInstanceStopped) => + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"ROR instance is being stopped") + case ReloadError(RawSettingsReloadError.ReloadingFailed(failure)) => + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ${failure.message}") + } + } + ) + } + + private def toWarningDto(warning: ImpersonationWarning): TestSettingsResponse.Warning = { + TestSettingsResponse.Warning( + blockName = warning.block.value, + ruleName = warning.ruleName.value, + message = warning.message.value, + hint = warning.hint + ) + } +} + +object TestRorSettingsApi { + + final case class TestSettingsRequest(aType: TestSettingsRequest.Type, + body: String) + + object TestSettingsRequest { + sealed trait Type + object Type { + case object ProvideTestSettings extends Type + case object UpdateTestSettings extends Type + case object InvalidateTestSettings extends Type + case object ProvideLocalUsers extends Type + } + } + + sealed trait TestSettingsResponse + object TestSettingsResponse { + + final case class Warning(blockName: String, + ruleName: String, + message: String, + hint: String) + + sealed trait ProvideTestSettings extends TestSettingsResponse + object ProvideTestSettings { + final case class CurrentTestSettings(ttl: FiniteDuration, + validTo: Instant, + settings: RawRorSettings, + warnings: List[Warning]) extends ProvideTestSettings + + final case class TestSettingsNotConfigured(message: String) extends ProvideTestSettings + final case class TestSettingsInvalidated(message: String, + settings: RawRorSettings, + ttl: FiniteDuration) extends ProvideTestSettings + } + + sealed trait UpdateTestSettings extends TestSettingsResponse + object UpdateTestSettings { + final case class SuccessResponse(message: String, validTo: Instant, warnings: List[Warning]) extends UpdateTestSettings + final case class FailedResponse(message: String) extends UpdateTestSettings + } + + sealed trait InvalidateTestSettings extends TestSettingsResponse + object InvalidateTestSettings { + final case class SuccessResponse(message: String) extends InvalidateTestSettings + final case class FailedResponse(message: String) extends InvalidateTestSettings + } + + sealed trait ProvideLocalUsers extends TestSettingsResponse + object ProvideLocalUsers { + final case class SuccessResponse(users: List[String], unknownUsers: Boolean) extends ProvideLocalUsers + final case class TestSettingsNotConfigured(message: String) extends ProvideLocalUsers + final case class TestSettingsInvalidated(message: String) extends ProvideLocalUsers + } + + sealed trait Failure extends TestSettingsResponse + object Failure { + final case class BadRequest(message: String) extends Failure + } + } + + implicit class StatusFromTestSettingsResponse(val response: TestSettingsResponse) extends AnyVal { + def status: String = response match { + case _: ProvideTestSettings.CurrentTestSettings => "TEST_SETTINGS_PRESENT" + case _: ProvideTestSettings.TestSettingsNotConfigured => "TEST_SETTINGS_NOT_CONFIGURED" + case _: ProvideTestSettings.TestSettingsInvalidated => "TEST_SETTINGS_INVALIDATED" + case _: UpdateTestSettings.SuccessResponse => "OK" + case _: UpdateTestSettings.FailedResponse => "FAILED" + case _: InvalidateTestSettings.SuccessResponse => "OK" + case _: InvalidateTestSettings.FailedResponse => "FAILED" + case _: ProvideLocalUsers.SuccessResponse => "OK" + case _: ProvideLocalUsers.TestSettingsNotConfigured => "TEST_SETTINGS_NOT_CONFIGURED" + case _: ProvideLocalUsers.TestSettingsInvalidated => "TEST_SETTINGS_INVALIDATED" + case _: Failure.BadRequest => "FAILED" + } + } + + private object Utils { + final case class UpdateTestSettingsRequest(settingsString: String, + ttl: PositiveFiniteDuration) + + private def parseDuration(value: String): Either[String, PositiveFiniteDuration] = { + Try(Duration(value)) + .toEither + .leftMap(_ => s"Cannot parse '${value.show}' as duration.") + .flatMap(_.toRefinedPositive) + } + + object decoders { + implicit val durationDecoder: Decoder[PositiveFiniteDuration] = Decoder.decodeString.emap(parseDuration) + + implicit val updateTestSettingsRequestDecoder: Decoder[UpdateTestSettingsRequest] = + Decoder.forProduct2("settings", "ttl")(UpdateTestSettingsRequest.apply) + } + + def apiFormat(duration: PositiveFiniteDuration): FiniteDuration = { + duration.value.toCoarsest + } + } +} diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 7ba56efad3..5c894a36ba 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -26,16 +26,18 @@ import tech.beshu.ror.accesscontrol.audit.{AuditingTool, LoggingContext} import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MutableMocksProviderWithCachePerRequest} import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, CoreFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, CoreFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.* import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.configuration.loader.RorMainSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -54,21 +56,19 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { rorYamlParser <- lift(new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) - indexConfigManager <- lift(new IndexJsonContentServiceBasedIndexMainSettingsManager(esConfig.rorConfigIndex, indexContentService, rorYamlParser)) - rorMainSettingsLoader <- lift(new RorMainSettingsManager(indexConfigManager)) - indexTestConfigManager <- lift(new IndexJsonContentServiceBasedIndexTestSettingsManager(esConfig.rorConfigIndex, indexContentService, rorYamlParser)) - rorTestSettingsLoader <- lift(new RorTestSettingsLoader(indexTestConfigManager)) - loadedRorConfig <- loadRorConfig(esConfig, rorMainSettingsLoader) - loadedTestRorConfig <- loadRorTestConfig(esConfig, rorTestSettingsLoader) - instance <- startRor(esConfig, loadedRorConfig, loadedTestRorConfig, indexConfigManager, indexTestConfigManager) + rorMainSettingsLoader <- lift(new RorMainSettingsManager( + new IndexJsonContentServiceBasedIndexMainSettingsManager(esConfig.rorSettingsIndex, indexContentService, rorYamlParser) + )) + rorTestSettingsLoader <- lift(new RorTestSettingsManager( + new IndexJsonContentServiceBasedIndexTestSettingsManager(esConfig.rorSettingsIndex, indexContentService, rorYamlParser) + )) + loadedMainRorSettings <- loadMainRorSettings(esConfig, rorMainSettingsLoader) + loadedTestRorSettings <- loadRorTestSettings(esConfig, rorTestSettingsLoader) + instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsLoader, loadedTestRorSettings, rorTestSettingsLoader) } yield instance).value } - private def lift[A](value: => A) = { - EitherT.liftF(Task.delay(value)) - } - - private def loadRorConfig(esConfig: EsConfigBasedRorSettings, + private def loadMainRorSettings(esConfig: EsConfigBasedRorSettings, rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => @@ -80,66 +80,67 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def loadRorTestConfig(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorTestSettingsLoader): EitherT[Task, StartingFailure, TestRorSettings] = { + private def loadRorTestSettings(esConfig: EsConfigBasedRorSettings, + rorSettingsLoader: RorTestSettingsManager): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => EitherT { rorSettingsLoader.loadFromIndexWithFallback( - indexLoadingSettings = settings, - fallbackConfig = notSetTestRorConfig + loadFromIndexParameters = parameters, + fallbackSettings = notSetTestRorSettings ) }.leftFlatMap { - case RorTestSettingsLoader.IndexParsingError(message) => + case LoadingFromIndexError.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) - case RorTestSettingsLoader.IndexUnknownStructure => + EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + case LoadingFromIndexError.IndexUnknownStructure => logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) - case RorTestSettingsLoader.IndexNotExist => + EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + case LoadingFromIndexError.IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorConfig) + EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) } } } - private def toStartingFailure(error: RorMainSettingsManager.Error) = { + private def toStartingFailure(error: LoadingError) = { error match { - case RorMainSettingsManager.FileParsingError(message) => + case LoadingFromFileError.FileParsingError(message) => StartingFailure(message) - case RorMainSettingsManager.FileNotExist(path) => + case LoadingFromFileError.FileNotExist(path) => StartingFailure(s"Cannot find settings file: ${path.show}") - case RorMainSettingsManager.IndexParsingError(message) => + case LoadingFromIndexError.IndexParsingError(message) => StartingFailure(message) - case RorMainSettingsManager.IndexUnknownStructure => + case LoadingFromIndexError.IndexUnknownStructure => StartingFailure(s"Settings index is malformed") - case RorMainSettingsManager.IndexNotExist => + case LoadingFromIndexError.IndexNotExist => StartingFailure(s"Settings index doesn't exist") } } private def startRor(esConfig: EsConfigBasedRorSettings, - loadedRorSettings: RawRorSettings, - loadedTestRorConfig: TestRorSettings, - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings]) = { + loadedMainRorSettings: RawRorSettings, + mainSettingsManager: RorMainSettingsManager, + loadedTestRorSettings: TestRorSettings, + testSettingsManager: RorTestSettingsManager) = { for { - mainEngine <- EitherT(loadRorEngine(loadedRorSettings, esConfig)) - testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorConfig)) - rorInstance <- createRorInstance(esConfig, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, loadedRorSettings) + mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfig)) + testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorSettings)) + rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsManager, testEngine, testSettingsManager, loadedMainRorSettings) } yield rorInstance } - private def loadTestEngine(esConfig: EsConfigBasedRorSettings, loadedTestRorConfig: TestRorSettings) = { - loadedTestRorConfig match { + private def loadTestEngine(esConfig: EsConfigBasedRorSettings, + loadedTestRorSettings: TestRorSettings) = { + loadedTestRorSettings match { case TestRorSettings.NotSet => Task.now(TestEngine.NotConfigured) - case config: TestRorSettings.Present if !config.isExpired(systemContext.clock) => - loadActiveTestEngine(esConfig, config) - case config: TestRorSettings.Present => - loadInvalidatedTestEngine(config) + case settings: TestRorSettings.Present if !settings.isExpired(systemContext.clock) => + loadActiveTestEngine(esConfig, settings) + case settings: TestRorSettings.Present => + loadInvalidatedTestEngine(settings) } } @@ -151,42 +152,41 @@ class ReadonlyRest(coreFactory: CoreFactory, case Right(loadedEngine) => TestEngine.Configured( engine = loadedEngine, - config = testSettings.rawSettings, - expiration = expirationConfig(testSettings.expiration) + settings = testSettings.rawSettings, + expiration = expirationFrom(testSettings.expiration) ) case Left(startingFailure) => logger.error(s"Unable to start test engine. Cause: ${startingFailure.message.show}. Test settings engine will be marked as invalidated.") - TestEngine.Invalidated(testSettings.rawSettings, expirationConfig(testSettings.expiration)) + TestEngine.Invalidated(testSettings.rawSettings, expirationFrom(testSettings.expiration)) } } yield testEngine } - private def loadInvalidatedTestEngine(testConfig: TestRorSettings.Present) = { + private def loadInvalidatedTestEngine(testSettings: TestRorSettings.Present) = { Task - .delay(authServicesMocksProvider.update(testConfig.mocks)) + .delay(authServicesMocksProvider.update(testSettings.mocks)) .map { _ => - TestEngine.Invalidated(testConfig.rawSettings, expirationConfig(testConfig.expiration)) + TestEngine.Invalidated(testSettings.rawSettings, expirationFrom(testSettings.expiration)) } } - private def expirationConfig(config: TestRorSettings.Present.ExpirationConfig): TestEngine.Expiration = { - TestEngine.Expiration(config.ttl, config.validTo) + private def expirationFrom(expiration: TestRorSettings.Present.Expiration): TestEngine.Expiration = { + TestEngine.Expiration(expiration.ttl, expiration.validTo) } private def createRorInstance(esConfig: EsConfigBasedRorSettings, - engine: Engine, + mainEngine: Engine, + mainSettingsManager: RorMainSettingsManager, testEngine: TestEngine, - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - loadedConfig: RawRorSettings) = { + testSettingsManager: RorTestSettingsManager, + alreadyLoadedSettings: RawRorSettings) = { EitherT.right[StartingFailure] { - val rorSettingsFile = esConfig.loadingRorCoreStrategy.rorSettingsFile val rorSettingsMaxSize = esConfig.loadingRorCoreStrategy.rorSettingsMaxSize esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, esConfig, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) + RorInstance.createWithoutPeriodicIndexCheck(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, esConfig, MainEngine(engine, loadedConfig), testEngine, indexConfigManager, indexTestConfigManager, settings.refreshInterval, rorSettingsFile, rorSettingsMaxSize) + RorInstance.createWithPeriodicIndexCheck(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager, settings.refreshInterval, rorSettingsMaxSize) } } } @@ -198,7 +198,7 @@ class ReadonlyRest(coreFactory: CoreFactory, EitherT( coreFactory - .createCoreFrom(rorSettings, esConfig.rorConfigIndex, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) + .createCoreFrom(rorSettings, esConfig.rorSettingsIndex, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) ) .flatMap(core => createEngine(httpClientsFactory, ldapConnectionPoolProvider, core)) .semiflatTap { engine => @@ -254,7 +254,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def handleLoadingCoreErrors(errors: NonEmptyList[RawRorConfigBasedCoreFactory.CoreCreationError]) = { + private def handleLoadingCoreErrors(errors: NonEmptyList[RawRorSettingsBasedCoreFactory.CoreCreationError]) = { val errorsMessage = errors .map(_.reason) .map { @@ -266,7 +266,11 @@ class ReadonlyRest(coreFactory: CoreFactory, StartingFailure(errorsMessage) } - private def notSetTestRorConfig: TestRorSettings = TestRorSettings.NotSet + private def notSetTestRorSettings: TestRorSettings = TestRorSettings.NotSet + + private def lift[A](value: => A) = { + EitherT.liftF(Task.delay(value)) + } } object ReadonlyRest { @@ -274,7 +278,7 @@ object ReadonlyRest { final case class StartingFailure(message: String, throwable: Option[Throwable] = None) final case class MainEngine(engine: Engine, - config: RawRorSettings) + settings: RawRorSettings) sealed trait TestEngine @@ -282,10 +286,10 @@ object ReadonlyRest { object NotConfigured extends TestEngine final case class Configured(engine: Engine, - config: RawRorSettings, + settings: RawRorSettings, expiration: Expiration) extends TestEngine - final case class Invalidated(config: RawRorSettings, + final case class Invalidated(settings: RawRorSettings, expiration: Expiration) extends TestEngine final case class Expiration(ttl: PositiveFiniteDuration, validTo: Instant) @@ -309,7 +313,7 @@ object ReadonlyRest { env: EsEnv) (implicit scheduler: Scheduler, systemContext: SystemContext): ReadonlyRest = { - val coreFactory: CoreFactory = new RawRorConfigBasedCoreFactory(env.esVersion) + val coreFactory: CoreFactory = new RawRorSettingsBasedCoreFactory(env.esVersion) create(coreFactory, indexContentService, auditSinkServiceCreator, env) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index ceb5619d34..417f8d538b 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.boot -import better.files.File import cats.Show import cats.effect.Resource import cats.implicits.toShow @@ -30,14 +29,12 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.factory.RorDependencies -import tech.beshu.ror.api.{AuthMockApi, ConfigApi, TestConfigApi} -import tech.beshu.ror.boot.engines.{Engines, MainConfigBasedReloadableEngine, TestConfigBasedReloadableEngine} +import tech.beshu.ror.api.{AuthMockApi, MainRorSettingsApi, TestRorSettingsApi} +import tech.beshu.ror.boot.engines.{Engines, MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.loader.FileRorSettingsLoader -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.loader.{RorMainSettingsManager, RorTestSettingsManager} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -46,13 +43,12 @@ import java.time.Instant class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, esConfig: EsConfigBasedRorSettings, - initialEngine: ReadonlyRest.MainEngine, + mainInitialEngine: ReadonlyRest.MainEngine, mainReloadInProgress: Semaphore[Task], - initialTestEngine: ReadonlyRest.TestEngine, + mainSettingsManager: RorMainSettingsManager, + testInitialEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorSettingsFile: File, + testSettingsManager: RorTestSettingsManager, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler) @@ -62,7 +58,7 @@ class RorInstance private(boot: ReadonlyRest, import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} logger.info("ReadonlyREST was loaded ...") - private val configsReloadTask = mode match { + private val enginesReloadTask = mode match { case Mode.WithPeriodicIndexCheck(RefreshInterval.Enabled(interval)) => scheduleEnginesReload(interval) case Mode.WithPeriodicIndexCheck(RefreshInterval.Disabled) | Mode.NoPeriodicIndexCheck => @@ -70,79 +66,78 @@ class RorInstance private(boot: ReadonlyRest, Cancelable.empty } - private val aMainConfigEngine = new MainConfigBasedReloadableEngine( + private val theMainSettingsEngine = new MainSettingsBasedReloadableEngine( boot, esConfig, - (initialEngine.engine, initialEngine.config), + (mainInitialEngine.engine, mainInitialEngine.settings), mainReloadInProgress, - indexConfigManager + mainSettingsManager ) - private val anTestConfigEngine = TestConfigBasedReloadableEngine.create( + private val theTestSettingsEngine = TestSettingsBasedReloadableEngine.create( boot, esConfig, - initialTestEngine, + testInitialEngine, testReloadInProgress, - indexTestConfigManager + testSettingsManager ) - private val rarRorConfigYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) + private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) - private val configRestApi = new ConfigApi( + private val mainSettingsRestApi = new MainRorSettingsApi( rorInstance = this, - rarRorConfigYamlParser, - indexConfigManager, - new FileRorSettingsLoader(rorSettingsFile, rarRorConfigYamlParser) + rarRorSettingsYamlParser, + mainSettingsManager ) private val authMockRestApi = new AuthMockApi(rorInstance = this) - private val testConfigRestApi = new TestConfigApi(rorInstance = this, rarRorConfigYamlParser) + private val testSettingsRestApi = new TestRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser) - def engines: Option[Engines] = aMainConfigEngine.engine.map(Engines(_, anTestConfigEngine.engine)) + def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) - def configApi: ConfigApi = configRestApi + def mainSettingsApi: MainRorSettingsApi = mainSettingsRestApi def authMockApi: AuthMockApi = authMockRestApi - def testConfigApi: TestConfigApi = testConfigRestApi + def testSettingsApi: TestRorSettingsApi = testSettingsRestApi def mocksProvider: MocksProvider = boot.authServicesMocksProvider def forceReloadFromIndex() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, Unit]] = - aMainConfigEngine.forceReloadFromIndex() + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = + theMainSettingsEngine.forceReloadFromIndex() - def forceReloadAndSave(config: RawRorSettings) - (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, Unit]] = - aMainConfigEngine.forceReloadAndSave(config) + def forceReloadAndSave(settings: RawRorSettings) + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, Unit]] = + theMainSettingsEngine.forceReloadAndSave(settings) - def currentTestConfig() - (implicit requestId: RequestId): Task[TestConfig] = { - anTestConfigEngine.currentTestConfig() + def currentTestSettings() + (implicit requestId: RequestId): Task[TestSettings] = { + theTestSettingsEngine.currentTestSettings() } - def forceReloadTestConfigEngine(config: RawRorSettings, - ttl: PositiveFiniteDuration) - (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, TestConfig.Present]] = { - anTestConfigEngine.forceReloadTestConfigEngine(config, ttl) + def forceReloadTestSettingsEngine(settings: RawRorSettings, + ttl: PositiveFiniteDuration) + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, TestSettings.Present]] = { + theTestSettingsEngine.forceReloadTestSettingsEngine(settings, ttl) } - def invalidateTestConfigEngine() - (implicit requestId: RequestId): Task[Either[IndexConfigInvalidationError, Unit]] = { - anTestConfigEngine.invalidateTestConfigEngine() + def invalidateTestSettingsEngine() + (implicit requestId: RequestId): Task[Either[IndexSettingsInvalidationError, Unit]] = { + theTestSettingsEngine.invalidateTestSettingsEngine() } def updateAuthMocks(mocks: AuthServicesMocks) - (implicit requestId: RequestId): Task[Either[IndexConfigUpdateError, Unit]] = { - anTestConfigEngine.saveConfig(mocks) + (implicit requestId: RequestId): Task[Either[IndexSettingsUpdateError, Unit]] = { + theTestSettingsEngine.saveServicesMocks(mocks) } def stop(): Task[Unit] = { implicit val requestId: RequestId = RequestId("ES sigterm") for { - _ <- Task.delay(configsReloadTask.cancel()) - _ <- anTestConfigEngine.stop() - _ <- aMainConfigEngine.stop() + _ <- Task.delay(enginesReloadTask.cancel()) + _ <- theTestSettingsEngine.stop() + _ <- theMainSettingsEngine.stop() } yield () } @@ -150,51 +145,51 @@ class RorInstance private(boot: ReadonlyRest, val reloadTask = { (requestId: RequestId) => Task.sequence { Seq( - tryMainEngineReload(requestId).map(result => (ConfigType.Main, result)), - tryTestEngineReload(requestId).map(result => (ConfigType.Test, result)) + tryMainEngineReload(requestId).map(result => (SettingsType.Main, result)), + tryTestEngineReload(requestId).map(result => (SettingsType.Test, result)) ) } } - scheduleIndexConfigChecking(interval, reloadTask) + scheduleIndexSettingsChecking(interval, reloadTask) } - private def scheduleIndexConfigChecking(interval: PositiveFiniteDuration, - reloadTask: RequestId => Task[Seq[(ConfigType, Either[ScheduledReloadError, Unit])]]): Cancelable = { + private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Cancelable = { logger.debug(s"[CLUSTERWIDE SETTINGS] Scheduling next in-index settings check within ${interval.show}") scheduler.scheduleOnce(interval.value) { implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST configs from index ...") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") reloadTask(requestId) .runAsync { case Right(reloadResults) => - reloadResults.foreach(logConfigReloadResult) - scheduleIndexConfigChecking(interval, reloadTask) + reloadResults.foreach(logSettingsReloadResult) + scheduleIndexSettingsChecking(interval, reloadTask) case Left(ex) => - logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index config failed: error", ex) - scheduleIndexConfigChecking(interval, reloadTask) + logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) + scheduleIndexSettingsChecking(interval, reloadTask) } } } - private def logConfigReloadResult(configReloadResult: (ConfigType, Either[ScheduledReloadError, Unit])) - (implicit requestId: RequestId): Unit = configReloadResult match { + private def logSettingsReloadResult(settingsReloadResult: (SettingsType, Either[ScheduledReloadError, Unit])) + (implicit requestId: RequestId): Unit = settingsReloadResult match { case (_, Right(())) => case (name, Left(ReloadingInProgress)) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Reloading of ${name.show} engine in progress ... skipping") - case (name, Left(EngineReloadError(IndexConfigReloadError.ReloadError(RawConfigReloadError.ConfigUpToDate(_))))) => + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ${name.show} settings are up to date. Nothing to reload.") - case (name, Left(EngineReloadError(IndexConfigReloadError.ReloadError(RawConfigReloadError.RorInstanceStopped)))) => + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Stopping periodic ${name.show} settings check - application is being stopped") - case (name, Left(EngineReloadError(IndexConfigReloadError.ReloadError(RawConfigReloadError.ReloadingFailed(startingFailure))))) => + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") - case (name, Left(EngineReloadError(IndexConfigReloadError.LoadingConfigError(error)))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} config from index failed: ${error.show}") + case (name, Left(EngineReloadError(IndexSettingsReloadError.LoadingSettingsError(error)))) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") } private def tryMainEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { withGuard(mainReloadInProgress) { - aMainConfigEngine - .reloadEngineUsingIndexConfigWithoutPermit()(requestId) + theMainSettingsEngine + .reloadEngineUsingIndexSettingsWithoutPermit()(requestId) .map(_.map(_ => ())) .map(_.leftMap(ScheduledReloadError.EngineReloadError.apply)) } @@ -202,8 +197,8 @@ class RorInstance private(boot: ReadonlyRest, private def tryTestEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { withGuard(testReloadInProgress) { - anTestConfigEngine - .reloadEngineUsingIndexConfigWithoutPermit()(requestId) + theTestSettingsEngine + .reloadEngineUsingIndexSettingsWithoutPermit()(requestId) .map(_.leftMap(ScheduledReloadError.EngineReloadError.apply)) } } @@ -224,89 +219,86 @@ class RorInstance private(boot: ReadonlyRest, object RorInstance { - sealed trait RawConfigReloadError - object RawConfigReloadError { - final case class ReloadingFailed(failure: ReadonlyRest.StartingFailure) extends RawConfigReloadError - final case class ConfigUpToDate(config: RawRorSettings) extends RawConfigReloadError - object RorInstanceStopped extends RawConfigReloadError + sealed trait RawSettingsReloadError + object RawSettingsReloadError { + final case class ReloadingFailed(failure: ReadonlyRest.StartingFailure) extends RawSettingsReloadError + final case class SettingsUpToDate(settings: RawRorSettings) extends RawSettingsReloadError + object RorInstanceStopped extends RawSettingsReloadError } - sealed trait IndexConfigReloadWithUpdateError - object IndexConfigReloadWithUpdateError { - final case class ReloadError(undefined: RawConfigReloadError) extends IndexConfigReloadWithUpdateError - final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigReloadWithUpdateError + sealed trait IndexSettingsReloadWithUpdateError + object IndexSettingsReloadWithUpdateError { + final case class ReloadError(undefined: RawSettingsReloadError) extends IndexSettingsReloadWithUpdateError + final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsReloadWithUpdateError } - sealed trait IndexConfigReloadError - object IndexConfigReloadError { - final case class LoadingConfigError(underlying: Error[LoadingIndexSettingsError]) extends IndexConfigReloadError - final case class ReloadError(underlying: RawConfigReloadError) extends IndexConfigReloadError + sealed trait IndexSettingsReloadError + object IndexSettingsReloadError { + final case class LoadingSettingsError(underlying: LoadingFromIndexError) extends IndexSettingsReloadError + final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError } - sealed trait IndexConfigUpdateError - object IndexConfigUpdateError { - final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigUpdateError - case object TestSettingsNotSet extends IndexConfigUpdateError - case object TestSettingsInvalidated extends IndexConfigUpdateError + sealed trait IndexSettingsUpdateError + object IndexSettingsUpdateError { + final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsUpdateError + case object TestSettingsNotSet extends IndexSettingsUpdateError + case object TestSettingsInvalidated extends IndexSettingsUpdateError } - sealed trait IndexConfigInvalidationError - object IndexConfigInvalidationError { - final case class IndexConfigSavingError(underlying: SavingIndexSettingsError) extends IndexConfigInvalidationError + sealed trait IndexSettingsInvalidationError + object IndexSettingsInvalidationError { + final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsInvalidationError } private sealed trait ScheduledReloadError private object ScheduledReloadError { case object ReloadingInProgress extends ScheduledReloadError - final case class EngineReloadError(underlying: IndexConfigReloadError) extends ScheduledReloadError + final case class EngineReloadError(underlying: IndexSettingsReloadError) extends ScheduledReloadError } - sealed trait TestConfig - object TestConfig { - case object NotSet extends TestConfig - final case class Present(rawConfig: RawRorSettings, + sealed trait TestSettings + object TestSettings { + case object NotSet extends TestSettings + final case class Present(rawSettings: RawRorSettings, dependencies: RorDependencies, configuredTtl: PositiveFiniteDuration, - validTo: Instant) extends TestConfig + validTo: Instant) extends TestSettings final case class Invalidated(recent: RawRorSettings, - configuredTtl: PositiveFiniteDuration) extends TestConfig + configuredTtl: PositiveFiniteDuration) extends TestSettings } def createWithPeriodicIndexCheck(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], + mainSettingsManager: RorMainSettingsManager, + testSettingsManager: RorTestSettingsManager, refreshInterval: RefreshInterval, - rorSettingsFile: File, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) + create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) } def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorSettingsFile: File, + mainSettingsManager: RorMainSettingsManager, + testSettingsManager: RorTestSettingsManager, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - create(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, indexConfigManager, indexTestConfigManager, rorSettingsFile, rorSettingsMaxSize) + create(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) } private def create(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, mode: RorInstance.Mode, - engine: ReadonlyRest.MainEngine, + mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - indexConfigManager: IndexSettingsManager[RawRorSettings], - indexTestConfigManager: IndexSettingsManager[TestRorSettings], - rorSettingsFile: File, + mainSettingsManager: RorMainSettingsManager, + testSettingsManager: RorTestSettingsManager, rorSettingsMaxSize: Information) (implicit systemContext: SystemContext, scheduler: Scheduler) = { @@ -317,13 +309,12 @@ object RorInstance { boot = boot, esConfig = esConfig, mode = mode, - initialEngine = engine, + mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, - initialTestEngine = testEngine, + mainSettingsManager = mainSettingsManager, + testInitialEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, - indexConfigManager = indexConfigManager, - indexTestConfigManager = indexTestConfigManager, - rorSettingsFile = rorSettingsFile, + testSettingsManager = testSettingsManager, rorSettingsMaxSize = rorSettingsMaxSize ) } @@ -334,12 +325,12 @@ object RorInstance { case object NoPeriodicIndexCheck extends Mode } - private sealed trait ConfigType - private object ConfigType { - case object Main extends ConfigType - case object Test extends ConfigType + private sealed trait SettingsType + private object SettingsType { + case object Main extends SettingsType + case object Test extends SettingsType - implicit val show: Show[ConfigType] = Show.show { + implicit val show: Show[SettingsType] = Show.show { case Main => "main" case Test => "test" } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index 9f559eb0b4..a8f31ae74c 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.Engine -import tech.beshu.ror.boot.RorInstance.RawConfigReloadError +import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet import tech.beshu.ror.boot.engines.ConfigHash.* @@ -128,20 +128,20 @@ private[engines] abstract class BaseReloadableEngine(val name: String, protected final def currentEngineState: EngineState = currentEngine.get() protected def reloadEngine(rorSettings: RawRorSettings) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { reloadEngineWithoutTtl(rorSettings) } protected def reloadEngine(newConfig: RawRorSettings, newConfigEngineTtl: PositiveFiniteDuration) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, ReloadResult] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { reloadEngineWithConfiguredTtl(newConfig, UpdatedConfigExpiration.ByTtl(newConfigEngineTtl)) } protected def reloadEngine(newConfig: RawRorSettings, newConfigExpirationTime: Instant, configuredTtl: PositiveFiniteDuration) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { isStillValid(newConfigExpirationTime) match { case RemainingEngineTime.Valid(_) => reloadEngineWithConfiguredTtl(newConfig, UpdatedConfigExpiration.ToTime(newConfigExpirationTime, configuredTtl)) @@ -167,7 +167,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, private def reloadEngineWithConfiguredTtl(newConfig: RawRorSettings, expiration: UpdatedConfigExpiration) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, ReloadResult] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { for { engineUpdateType <- checkUpdateType(newConfig, expiration) expirationConfig <- engineUpdateType match { @@ -178,13 +178,13 @@ private[engines] abstract class BaseReloadableEngine(val name: String, case EngineUpdateType.UpdateConfigTtl => updateEngineExpirationConfig(expiration) case EngineUpdateType.ConfigAndTtlUpToDate(engine, expirationConfig) => - EitherT.right[RawConfigReloadError](Task.now(ReloadResult(engine, expirationConfig))) + EitherT.right[RawSettingsReloadError](Task.now(ReloadResult(engine, expirationConfig))) } } yield expirationConfig } private def reloadEngineWithoutTtl(rorSettings: RawRorSettings) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { for { _ <- canBeReloaded(rorSettings) _ <- runReload(rorSettings, None) @@ -193,7 +193,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, private def runReload(rorSettings: RawRorSettings, configExpiration: Option[UpdatedConfigExpiration]) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, EngineWithConfig] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, EngineWithConfig] = { for { newEngineWithConfig <- reloadWith(rorSettings, configExpiration) _ <- replaceCurrentEngine(newEngineWithConfig) @@ -201,7 +201,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def checkUpdateType(newConfig: RawRorSettings, - newConfigExpiration: UpdatedConfigExpiration): EitherT[Task, RawConfigReloadError, EngineUpdateType] = { + newConfigExpiration: UpdatedConfigExpiration): EitherT[Task, RawSettingsReloadError, EngineUpdateType] = { EitherT { Task.delay { currentEngine.get() match { @@ -212,7 +212,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, case EngineState.Working(EngineWithConfig(engine, _, engineExpirationConfig), _) => checkIfExpirationConfigHasChanged(engine, newConfigExpiration, engineExpirationConfig) case EngineState.Stopped => - Left(RawConfigReloadError.RorInstanceStopped) + Left(RawSettingsReloadError.RorInstanceStopped) } } } @@ -234,7 +234,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def canBeReloaded(newConfig: RawRorSettings): EitherT[Task, RawConfigReloadError, Unit] = { + private def canBeReloaded(newConfig: RawRorSettings): EitherT[Task, RawSettingsReloadError, Unit] = { EitherT { Task.delay { currentEngine.get() match { @@ -243,16 +243,16 @@ private[engines] abstract class BaseReloadableEngine(val name: String, case EngineState.Working(EngineWithConfig(_, currentConfig, _), _) if currentConfig != newConfig => Right(()) case EngineState.Working(EngineWithConfig(_, currentConfig, _), _) => - Left(RawConfigReloadError.ConfigUpToDate(currentConfig)) + Left(RawSettingsReloadError.SettingsUpToDate(currentConfig)) case EngineState.Stopped => - Left(RawConfigReloadError.RorInstanceStopped) + Left(RawSettingsReloadError.RorInstanceStopped) } } } } private def reloadWith(rorSettings: RawRorSettings, - configExpiration: Option[UpdatedConfigExpiration]): EitherT[Task, RawConfigReloadError, EngineWithConfig] = EitherT { + configExpiration: Option[UpdatedConfigExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithConfig] = EitherT { tryToLoadRorCore(rorSettings) .map(_ .map { engine => @@ -262,7 +262,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, expirationConfig = configExpiration.map(engineExpirationConfig) ) } - .leftMap(RawConfigReloadError.ReloadingFailed.apply) + .leftMap(RawSettingsReloadError.ReloadingFailed.apply) ) } @@ -279,7 +279,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, boot.loadRorEngine(rorSettings, esConfig) private def replaceCurrentEngine(newEngineWithConfig: EngineWithConfig) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, Unit] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { EitherT { Task.delay { val oldEngineState = currentEngine.getAndTransform { @@ -298,7 +298,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, oldEngineState match { case _: EngineState.NotStartedYet => Right(()) case EngineState.Working(_, _) => Right(()) - case EngineState.Stopped => Left(RawConfigReloadError.RorInstanceStopped) + case EngineState.Stopped => Left(RawSettingsReloadError.RorInstanceStopped) } } } @@ -362,7 +362,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def updateEngineExpirationConfig(configExpiration: UpdatedConfigExpiration) - (implicit requestId: RequestId): EitherT[Task, RawConfigReloadError, ReloadResult] = { + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { EitherT { Task.delay { val newEngineState = currentEngine.transformAndGet { @@ -378,11 +378,11 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } newEngineState match { case _: EngineState.NotStartedYet => - Left(RawConfigReloadError.ReloadingFailed(ReadonlyRest.StartingFailure("Cannot update engine TTL because engine was invalidated"))) + Left(RawSettingsReloadError.ReloadingFailed(ReadonlyRest.StartingFailure("Cannot update engine TTL because engine was invalidated"))) case EngineState.Working(engineWithConfig, _) => Right(ReloadResult(engineWithConfig.engine, engineWithConfig.expirationConfig.get)) case EngineState.Stopped => - Left(RawConfigReloadError.RorInstanceStopped) + Left(RawSettingsReloadError.RorInstanceStopped) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala similarity index 59% rename from core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala rename to core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 80a2f14c3a..9ab17cb232 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -25,23 +25,23 @@ import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.boot.RorInstance.* -import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} -import tech.beshu.ror.boot.RorInstance.RawConfigReloadError.{ConfigUpToDate, ReloadingFailed, RorInstanceStopped} +import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} +import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.ConfigHash.* import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} -import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError +import tech.beshu.ror.configuration.loader.RorMainSettingsManager +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value -private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - initialEngine: (Engine, RawRorSettings), - reloadInProgress: Semaphore[Task], - indexConfigManager: IndexSettingsManager[RawRorSettings]) - (implicit systemContext: SystemContext, - scheduler: Scheduler) +private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, + initialEngine: (Engine, RawRorSettings), + reloadInProgress: Semaphore[Task], + settingsManager: RorMainSettingsManager) + (implicit systemContext: SystemContext, + scheduler: Scheduler) extends BaseReloadableEngine( name = "main", boot = boot, @@ -51,13 +51,13 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, ) { def forceReloadAndSave(config: RawRorSettings) - (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, Unit]] = { + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, Unit]] = { for { _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${config.hashString()}) ...")) reloadResult <- reloadInProgress.withPermit { value { for { - _ <- reloadEngine(config).leftMap(IndexConfigReloadWithUpdateError.ReloadError.apply) + _ <- reloadEngine(config).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) _ <- saveConfig(config) } yield () } @@ -65,7 +65,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, _ <- Task.delay(reloadResult match { case Right(_) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) settings reloaded!") - case Left(ReloadError(ConfigUpToDate(oldConfig))) => + case Left(ReloadError(SettingsUpToDate(oldConfig))) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldConfig.hashString().show}) already loaded!") case Left(ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => logger.error(s"[${requestId.show}] [${config.hashString()}] Cannot reload ROR settings - failure: ${message.show}", ex) @@ -73,7 +73,7 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexConfigSavingError(SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveSettings)) => // todo: invalidate created core? logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") }) @@ -81,55 +81,58 @@ private[boot] class MainConfigBasedReloadableEngine(boot: ReadonlyRest, } def forceReloadFromIndex() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, Unit]] = { + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = { for { _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of in-index settings was forced ...")) reloadResult <- reloadEngineUsingIndexConfig() _ <- Task.delay(reloadResult match { case Right(config) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) settings reloaded!") - case Left(IndexConfigReloadError.ReloadError(ConfigUpToDate(config))) => + case Left(IndexSettingsReloadError.ReloadError(SettingsUpToDate(config))) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) already loaded!") - case Left(IndexConfigReloadError.ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => + case Left(IndexSettingsReloadError.ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}", ex) - case Left(IndexConfigReloadError.ReloadError(ReloadingFailed(StartingFailure(message, None)))) => + case Left(IndexSettingsReloadError.ReloadError(ReloadingFailed(StartingFailure(message, None)))) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") - case Left(IndexConfigReloadError.ReloadError(RorInstanceStopped)) => + case Left(IndexSettingsReloadError.ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexConfigReloadError.LoadingConfigError(error)) => + case Left(IndexSettingsReloadError.LoadingSettingsError(error)) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${error.show}") }) } yield reloadResult.map(_ => ()) } def reloadEngineUsingIndexConfig() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorSettings]] = { + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { reloadInProgress.withPermit { - reloadEngineUsingIndexConfigWithoutPermit() + reloadEngineUsingIndexSettingsWithoutPermit() } } - private[boot] def reloadEngineUsingIndexConfigWithoutPermit() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, RawRorSettings]] = { + private[boot] def reloadEngineUsingIndexSettingsWithoutPermit() + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { val result = for { - newConfig <- EitherT(loadRorConfigFromIndex()) - _ <- reloadEngine(newConfig) - .leftMap(IndexConfigReloadError.ReloadError.apply) - .leftWiden[IndexConfigReloadError] - } yield newConfig + newSettings <- loadRorSettingFromIndex() + _ <- reloadEngine(newSettings) + .leftMap(IndexSettingsReloadError.ReloadError.apply) + .leftWiden[IndexSettingsReloadError] + } yield newSettings result.value } - private def saveConfig(newConfig: RawRorSettings): EitherT[Task, IndexConfigReloadWithUpdateError, Unit] = EitherT { + private def saveConfig(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = EitherT { for { - saveResult <- indexConfigManager.save(newConfig) - } yield saveResult.left.map(IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply) + saveResult <- settingsManager.saveToIndex(settings) + } yield saveResult.left.map(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) } - private def loadRorConfigFromIndex() = { - indexConfigManager - .load() - .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) + private def loadRorSettingFromIndex() = { + EitherT(settingsManager.loadFromIndex()) + .leftMap { + case LoadingFromIndexError.IndexParsingError(message) => ??? + case LoadingFromIndexError.IndexUnknownStructure => ??? + case LoadingFromIndexError.IndexNotExist => ??? + } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala similarity index 62% rename from core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala rename to core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 555924556d..e21c8c9c95 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestConfigBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -26,54 +26,54 @@ import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.{StartingFailure, TestEngine} import tech.beshu.ror.boot.RorInstance.* -import tech.beshu.ror.boot.RorInstance.IndexConfigReloadWithUpdateError.{IndexConfigSavingError, ReloadError} +import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpirationConfig, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.TestRorSettings.Present.ExpirationConfig -import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError +import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration +import tech.beshu.ror.configuration.loader.RorTestSettingsManager +import tech.beshu.ror.configuration.loader.SettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value -private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - initialEngine: InitialEngine, - reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexSettingsManager[TestRorSettings]) - (implicit systemContext: SystemContext, - scheduler: Scheduler) +private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, + initialEngine: InitialEngine, + reloadInProgress: Semaphore[Task], + testSettingsManager: RorTestSettingsManager) + (implicit systemContext: SystemContext, + scheduler: Scheduler) extends BaseReloadableEngine("test", boot, esConfig, initialEngine, reloadInProgress) { - def currentTestConfig() - (implicit requestId: RequestId): Task[TestConfig] = { + def currentTestSettings() + (implicit requestId: RequestId): Task[TestSettings] = { Task.delay { currentEngineState match { case EngineState.NotStartedYet(None, _) | EngineState.Stopped => - TestConfig.NotSet + TestSettings.NotSet case EngineState.NotStartedYet(Some(recentConfig), recentExpirationConfig) => val expiration = recentExpirationConfig.getOrElse(throw new IllegalStateException("Test Config based engine should have an expiration config defined")) - TestConfig.Invalidated(recentConfig, expiration.ttl) + TestSettings.Invalidated(recentConfig, expiration.ttl) case EngineState.Working(engineWithConfig, _) => val expiration = engineWithConfig.expirationConfig.getOrElse(throw new IllegalStateException("Test Config based engine should have an expiration config defined")) - TestConfig.Present(engineWithConfig.config, engineWithConfig.engine.core.dependencies, expiration.ttl, expiration.validTo) + TestSettings.Present(engineWithConfig.config, engineWithConfig.engine.core.dependencies, expiration.ttl, expiration.validTo) } } } - def forceReloadTestConfigEngine(config: RawRorSettings, - ttl: PositiveFiniteDuration) - (implicit requestId: RequestId): Task[Either[IndexConfigReloadWithUpdateError, TestConfig.Present]] = { + def forceReloadTestSettingsEngine(config: RawRorSettings, + ttl: PositiveFiniteDuration) + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, TestSettings.Present]] = { for { _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of ROR test settings was forced (TTL of test engine is ${ttl.show}) ...")) reloadResult <- reloadInProgress.withPermit { value { for { - engineExpirationConfig <- reloadEngine(config, ttl).leftMap(IndexConfigReloadWithUpdateError.ReloadError.apply) + engineExpirationConfig <- reloadEngine(config, ttl).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) testRorConfig = TestRorSettings.Present( rawSettings = config, - expiration = TestRorSettings.Present.ExpirationConfig( + expiration = TestRorSettings.Present.Expiration( ttl = engineExpirationConfig.expirationConfig.ttl, validTo = engineExpirationConfig.expirationConfig.validTo ), @@ -81,12 +81,12 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, ) _ <- saveConfigInIndex( newConfig = testRorConfig, - onFailure = IndexConfigReloadWithUpdateError.IndexConfigSavingError.apply + onFailure = IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply ) - .leftWiden[IndexConfigReloadWithUpdateError] - } yield TestConfig.Present( + .leftWiden[IndexSettingsReloadWithUpdateError] + } yield TestSettings.Present( dependencies = engineExpirationConfig.engine.core.dependencies, - rawConfig = config, + rawSettings = config, configuredTtl = engineExpirationConfig.expirationConfig.ttl, validTo = engineExpirationConfig.expirationConfig.validTo ) @@ -95,22 +95,22 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, _ <- Task.delay(reloadResult match { case Right(_) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) reloaded!") - case Left(ReloadError(RawConfigReloadError.ConfigUpToDate(oldConfig))) => + case Left(ReloadError(RawSettingsReloadError.SettingsUpToDate(oldConfig))) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldConfig.hashString().show}) already loaded!") - case Left(ReloadError(RawConfigReloadError.ReloadingFailed(StartingFailure(message, Some(ex))))) => + case Left(ReloadError(RawSettingsReloadError.ReloadingFailed(StartingFailure(message, Some(ex))))) => logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}", ex) - case Left(ReloadError(RawConfigReloadError.ReloadingFailed(StartingFailure(message, None)))) => + case Left(ReloadError(RawSettingsReloadError.ReloadingFailed(StartingFailure(message, None)))) => logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}") - case Left(ReloadError(RawConfigReloadError.RorInstanceStopped)) => + case Left(ReloadError(RawSettingsReloadError.RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading tests settings skipped!") - case Left(IndexConfigSavingError(SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveSettings)) => logger.error(s"[${requestId.show}] Saving ROR test settings in index failed") }) } yield reloadResult } - def invalidateTestConfigEngine() - (implicit requestId: RequestId): Task[Either[IndexConfigInvalidationError, Unit]] = { + def invalidateTestSettingsEngine() + (implicit requestId: RequestId): Task[Either[IndexSettingsInvalidationError, Unit]] = { reloadInProgress.withPermit { for { invalidated <- invalidate(keepPreviousConfiguration = true) @@ -118,7 +118,7 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, case Some(invalidatedEngine) => val config = TestRorSettings.Present( rawSettings = invalidatedEngine.config, - expiration = ExpirationConfig( + expiration = Expiration( ttl = invalidatedEngine.expirationConfig.ttl, validTo = invalidatedEngine.expirationConfig.validTo ), @@ -126,9 +126,9 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, ) saveConfigInIndex( newConfig = config, - onFailure = IndexConfigInvalidationError.IndexConfigSavingError.apply + onFailure = IndexSettingsInvalidationError.IndexSettingsSavingError.apply ) - .leftWiden[IndexConfigInvalidationError] + .leftWiden[IndexSettingsInvalidationError] .value case None => Task.now(Right(())) @@ -137,24 +137,24 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, } } - def saveConfig(mocks: AuthServicesMocks) - (implicit requestId: RequestId): Task[Either[IndexConfigUpdateError, Unit]] = { + def saveServicesMocks(mocks: AuthServicesMocks) + (implicit requestId: RequestId): Task[Either[IndexSettingsUpdateError, Unit]] = { reloadInProgress.withPermit { value { for { config <- readCurrentTestConfigForUpdate() _ <- updateMocksProvider(mocks) testRorConfig = TestRorSettings.Present( - rawSettings = config.rawConfig, - expiration = TestRorSettings.Present.ExpirationConfig( + rawSettings = config.rawSettings, + expiration = TestRorSettings.Present.Expiration( ttl = config.configuredTtl, validTo = config.validTo ), mocks = boot.authServicesMocksProvider.currentMocks ) - _ <- saveConfigInIndex[IndexConfigUpdateError]( + _ <- saveConfigInIndex[IndexSettingsUpdateError]( newConfig = testRorConfig, - onFailure = IndexConfigUpdateError.IndexConfigSavingError.apply + onFailure = IndexSettingsUpdateError.IndexSettingsSavingError.apply ) } yield () } @@ -162,16 +162,16 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, } private def readCurrentTestConfigForUpdate() - (implicit requestId: RequestId): EitherT[Task, IndexConfigUpdateError, TestConfig.Present] = { + (implicit requestId: RequestId): EitherT[Task, IndexSettingsUpdateError, TestSettings.Present] = { EitherT { - currentTestConfig() + currentTestSettings() .map { - case TestConfig.NotSet => - Left(IndexConfigUpdateError.TestSettingsNotSet) - case config: TestConfig.Present => + case TestSettings.NotSet => + Left(IndexSettingsUpdateError.TestSettingsNotSet) + case config: TestSettings.Present => Right(config) - case _: TestConfig.Invalidated => - Left(IndexConfigUpdateError.TestSettingsInvalidated) + case _: TestSettings.Invalidated => + Left(IndexSettingsUpdateError.TestSettingsInvalidated) } } } @@ -182,34 +182,34 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, private def saveConfigInIndex[A](newConfig: TestRorSettings.Present, onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { - EitherT(indexTestConfigManager.save(newConfig)) + EitherT(testSettingsManager.saveToIndex(newConfig)) .leftMap(onFailure) } - private[boot] def reloadEngineUsingIndexConfigWithoutPermit() - (implicit requestId: RequestId): Task[Either[IndexConfigReloadError, Unit]] = { + private[boot] def reloadEngineUsingIndexSettingsWithoutPermit() + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = { value { for { loadedConfig <- loadRorConfigFromIndex() config <- loadedConfig match { case TestRorSettings.NotSet => - invalidateTestConfigByIndex[IndexConfigReloadError]() + invalidateTestConfigByIndex[IndexSettingsReloadError]() case TestRorSettings.Present(rawConfig, mocks, expiration) => for { _ <- reloadEngine(rawConfig, expiration.validTo, expiration.ttl) - .leftMap(IndexConfigReloadError.ReloadError.apply) - .leftWiden[IndexConfigReloadError] - _ <- updateMocksProvider[IndexConfigReloadError](mocks) + .leftMap(IndexSettingsReloadError.ReloadError.apply) + .leftWiden[IndexSettingsReloadError] + _ <- updateMocksProvider[IndexSettingsReloadError](mocks) } yield () } } yield config } } - private def loadRorConfigFromIndex(): EitherT[Task, IndexConfigReloadError, TestRorSettings] = EitherT { - indexTestConfigManager - .load() - .map(_.left.map(IndexConfigReloadError.LoadingConfigError.apply)) + private def loadRorConfigFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = EitherT { + testSettingsManager + .loadFromIndex() + .map(_.left.map(IndexSettingsReloadError.LoadingSettingsError.apply)) } private def invalidateTestConfigByIndex[A]() @@ -231,14 +231,14 @@ private[boot] class TestConfigBasedReloadableEngine private(boot: ReadonlyRest, } -object TestConfigBasedReloadableEngine { +object TestSettingsBasedReloadableEngine { def create(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], - indexTestConfigManager: IndexSettingsManager[TestRorSettings]) + testSettingsManager: RorTestSettingsManager) (implicit systemContext: SystemContext, - scheduler: Scheduler): TestConfigBasedReloadableEngine = { + scheduler: Scheduler): TestSettingsBasedReloadableEngine = { val engine = initialEngine match { case TestEngine.NotConfigured => InitialEngine.NotConfigured @@ -247,7 +247,7 @@ object TestConfigBasedReloadableEngine { case TestEngine.Invalidated(config, expiration) => InitialEngine.Invalidated(config, expirationConfig(expiration)) } - new TestConfigBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, indexTestConfigManager) + new TestSettingsBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, testSettingsManager) } private def expirationConfig(config: TestEngine.Expiration) = EngineExpirationConfig(config.ttl, config.validTo) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index 565a393e88..8e27ee1ef9 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -37,7 +37,7 @@ import scala.language.implicitConversions final case class EsConfigBasedRorSettings(boot: RorBootSettings, ssl: Option[RorSslSettings], - rorConfigIndex: RorSettingsIndex, + rorSettingsIndex: RorSettingsIndex, loadingRorCoreStrategy: LoadingRorCoreStrategy) object EsConfigBasedRorSettings { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala index 84d206b844..c63ae345d3 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala @@ -159,6 +159,8 @@ object RorProperties extends Logging { final case class LoadingDelay(value: NonNegativeFiniteDuration) extends AnyVal object LoadingDelay { + val none: LoadingDelay = unsafeFrom(0 seconds) + def unsafeFrom(value: FiniteDuration): LoadingDelay = LoadingDelay(value.toRefinedNonNegativeUnsafe) implicit val show: Show[LoadingDelay] = Show[FiniteDuration].contramap(_.value.value) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala index c4342f8f80..eda8c505f9 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala @@ -27,13 +27,13 @@ object TestRorSettings { case object NotSet extends TestRorSettings final case class Present(rawSettings: RawRorSettings, mocks: AuthServicesMocks, - expiration: Present.ExpirationConfig) extends TestRorSettings { + expiration: Present.Expiration) extends TestRorSettings { def isExpired(clock: Clock): Boolean = { expiration.validTo.isBefore(clock.instant()) } } object Present { - final case class ExpirationConfig(ttl: PositiveFiniteDuration, validTo: Instant) + final case class Expiration(ttl: PositiveFiniteDuration, validTo: Instant) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index eb3cc59ec0..4bfa8b6aad 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -final class IndexJsonContentServiceBasedIndexMainSettingsManager(settingsIndex: RorSettingsIndex, +final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[RawRorSettings] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index be6e11c87d..89dcc02c56 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -51,7 +51,7 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -final class IndexJsonContentServiceBasedIndexTestSettingsManager(settingsIndex: RorSettingsIndex, +final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, rarRorConfigYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[TestRorSettings] @@ -101,7 +101,7 @@ final class IndexJsonContentServiceBasedIndexTestSettingsManager(settingsIndex: } yield Present( rawSettings = rawRorConfig, mocks = mocks, - expiration = Present.ExpirationConfig(ttl = expirationTtl, validTo = expirationTime) + expiration = Present.Expiration(ttl = expirationTtl, validTo = expirationTime) ) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala index 48ceb76aec..273408fee6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -18,6 +18,7 @@ package tech.beshu.ror.configuration.index import cats.Show import monix.eval.Task +import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.loader.RorSettingsLoader import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError @@ -26,6 +27,8 @@ import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedEr // todo: it looks like this manager should extend RorConfigLoader trait IndexSettingsManager[SETTINGS] { + def settingsIndex: RorSettingsIndex + def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala index 9323780a27..e312c3f846 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala @@ -16,15 +16,18 @@ */ package tech.beshu.ror.configuration.loader +import cats.Show import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParameters, LoadFromIndexParameters} -import tech.beshu.ror.configuration.RorProperties.LoadingAttemptsCount +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +import tech.beshu.ror.configuration.loader.RorMainSettingsManager.LoadingFromFileError import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* @@ -33,35 +36,51 @@ import scala.language.postfixOps // todo: refactor methods class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSettings]) - extends Logging { + extends SettingsManager[RawRorSettings] with Logging { - def loadFromFile(loadFromFileParameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + def loadFromFile(loadFromFileParameters: LoadFromFileParameters): Task[Either[LoadingFromFileError, RawRorSettings]] = { forceLoadFromFile(loadFromFileParameters) } - def loadFromIndexWithFileFallback(loadFromIndexParameters: LoadFromIndexParameters, - loadFromFileParameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { + loadRorSettingsFromIndex(loadingDelay = LoadingDelay.none) + } + + override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { attemptLoadingFromIndex( parameters = loadFromIndexParameters, - fallback = loadRorSettingsFromFile(loadFromFileParameters) + fallback = fallback + ) + } + + def loadFromIndexWithFileFallback(loadFromIndexParameters: LoadFromIndexParameters, + loadFromFileParameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { + loadFromIndexWithFallback( + loadFromIndexParameters, + loadRorSettingsFromFile(loadFromFileParameters) ) } + override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { + ??? + } + private def attemptLoadingFromIndex(parameters: LoadFromIndexParameters, - fallback: Task[Either[RorMainSettingsManager.Error, RawRorSettings]]): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { parameters.loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => - loadRorSettingsFromIndex(parameters).flatMap { - case Left(RorMainSettingsManager.IndexNotExist) => + loadRorSettingsFromIndex(parameters.loadingDelay).flatMap { + case Left(LoadingFromIndexError.IndexNotExist) => attemptLoadingFromIndex( parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), fallback = fallback ) - case Left(RorMainSettingsManager.IndexUnknownStructure) => - Task.now(Left(RorMainSettingsManager.IndexUnknownStructure)) - case Left(error@RorMainSettingsManager.IndexParsingError(_)) => + case Left(LoadingFromIndexError.IndexUnknownStructure) => + Task.now(Left(LoadingFromIndexError.IndexUnknownStructure)) + case Left(error@LoadingFromIndexError.IndexParsingError(_)) => Task.now(Left(error)) case Right(value) => Task.now(Right(value)) @@ -69,13 +88,13 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } } - private def loadRorSettingsFromIndex(parameters: LoadFromIndexParameters) = { - val rorSettingsIndex = parameters.rorSettingsIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${rorSettingsIndex.index.show}) ...") + private def loadRorSettingsFromIndex(loadingDelay: LoadingDelay) = { + val settingsIndex = indexSettingsManager.settingsIndex + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...") EitherT { indexSettingsManager .load() - .delayExecution(parameters.loadingDelay.value.value) + .delayExecution(loadingDelay.value.value) } .map { rorSettings => logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw ReadonlyREST settings from index: ${rorSettings.raw.show}") @@ -90,7 +109,7 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } // todo: these two are almost the same (logging differs only) - private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { val rorSettingsFile = parameters.rorSettingsFile val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") @@ -103,7 +122,7 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe .value } - private def forceLoadFromFile(parameters: LoadFromFileParameters): Task[Either[RorMainSettingsManager.Error, RawRorSettings]] = { + private def forceLoadFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingFromFileError, RawRorSettings]] = { val rorSettingsFile = parameters.rorSettingsFile val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") @@ -116,43 +135,39 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe .value } - private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): RorMainSettingsManager.Error = { + private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { error match { - case ParsingError(error) => - val show = error.show - RorMainSettingsManager.FileParsingError(show) - case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => RorMainSettingsManager.FileNotExist(file.path) + case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) + case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) } } private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]) = error match { - case ParsingError(error) => RorMainSettingsManager.IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => RorMainSettingsManager.IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => RorMainSettingsManager.IndexUnknownStructure + case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure } - private def logIndexLoadingError[A](error: RorMainSettingsManager.LoadingIndexError): Unit = { + private def logIndexLoadingError[A](error: LoadingFromIndexError): Unit = { error match { - case RorMainSettingsManager.IndexParsingError(message) => + case LoadingFromIndexError.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case RorMainSettingsManager.IndexUnknownStructure => + case LoadingFromIndexError.IndexUnknownStructure => logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") - case RorMainSettingsManager.IndexNotExist => + case LoadingFromIndexError.IndexNotExist => logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") } } - } object RorMainSettingsManager { - // todo: do we need two hierarchies? - sealed trait Error - final case class FileParsingError(message: String) extends Error - final case class FileNotExist(path: Path) extends Error + sealed trait LoadingFromFileError extends LoadingError + object LoadingFromFileError { + final case class FileParsingError(message: String) extends LoadingFromFileError + final case class FileNotExist(path: Path) extends LoadingFromFileError + + implicit val show: Show[LoadingFromFileError] = ??? + } - sealed trait LoadingIndexError extends Error - final case class IndexParsingError(message: String) extends Error with LoadingIndexError - case object IndexUnknownStructure extends Error with LoadingIndexError - case object IndexNotExist extends Error with LoadingIndexError } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala similarity index 52% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala rename to core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala index e30db03425..2c31940c4e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala @@ -25,47 +25,60 @@ import tech.beshu.ror.configuration.TestRorSettings import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.RorTestSettingsLoader.{IndexNotExist, IndexParsingError, IndexUnknownStructure, LoadingIndexError} +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.implicits.* -import scala.concurrent.duration.DurationInt import scala.language.postfixOps -class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSettings]) - extends Logging { +class RorTestSettingsManager(indexConfigManager: IndexSettingsManager[TestRorSettings]) + extends SettingsManager[TestRorSettings] with Logging { - def loadFromIndexWithFallback(indexLoadingSettings: LoadFromIndexParameters, - fallbackConfig: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { + def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + fallbackSettings: TestRorSettings): Task[Either[LoadingFromIndexError, TestRorSettings]] = { + loadFromIndexWithFallback( + loadFromIndexParameters = loadFromIndexParameters, + fallback = Task.delay(Right(fallbackSettings)) + ).map(_.leftMap { + case error: LoadingFromIndexError => error + case error => throw new IllegalStateException(s"Unexpected $error type") + }) + } + + override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { attemptLoadingConfigFromIndex( - settings = indexLoadingSettings, - fallback = fallbackConfig + parameters = loadFromIndexParameters, + fallback = fallback ) } - private def attemptLoadingConfigFromIndex(settings: LoadFromIndexParameters, - fallback: TestRorSettings): Task[Either[LoadingIndexError, TestRorSettings]] = { - settings.loadingAttemptsCount.value.value match { + override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { + ??? + } + + override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { + ??? + } + + private def attemptLoadingConfigFromIndex(parameters: LoadFromIndexParameters, + fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { + parameters.loadingAttemptsCount.value.value match { case 0 => - Task.now(Right(fallback)) + fallback case attemptsCount => - for { - result <- loadTestRorConfigFromIndex( - settings.copy(loadingDelay = LoadingDelay.unsafeFrom(0 seconds)) - ) - rawRorConfig <- result match { - case Left(IndexNotExist) => - attemptLoadingConfigFromIndex( - settings.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(settings.loadingAttemptsCount.value.value - 1)), - fallback = fallback - ) - case Left(error@IndexUnknownStructure) => - Task.now(Left(error)) - case Left(error@IndexParsingError(_)) => - Task.now(Left(error)) - case Right(value) => - Task.now(Right(value)) - } - } yield rawRorConfig + loadTestRorConfigFromIndex(parameters.copy(loadingDelay = LoadingDelay.none)).flatMap { + case Left(LoadingFromIndexError.IndexNotExist) => + attemptLoadingConfigFromIndex( + parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), + fallback = fallback + ) + case Left(error@LoadingFromIndexError.IndexUnknownStructure) => + Task.now(Left(error)) + case Left(error@LoadingFromIndexError.IndexParsingError(_)) => + Task.now(Left(error)) + case Right(value) => + Task.now(Right(value)) + } } } @@ -96,29 +109,22 @@ class RorTestSettingsLoader(indexConfigManager: IndexSettingsManager[TestRorSett .value } - private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingIndexError = + private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingFromIndexError = error match { - case ParsingError(error) => IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => IndexUnknownStructure + case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) + case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist + case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure } - private def logIndexLoadingError(error: LoadingIndexError): Unit = { + private def logIndexLoadingError(error: LoadingFromIndexError): Unit = { error match { - case IndexParsingError(message) => + case LoadingFromIndexError.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case IndexUnknownStructure => + case LoadingFromIndexError.IndexUnknownStructure => logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") - case IndexNotExist => + case LoadingFromIndexError.IndexNotExist => logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") } } } - -object RorTestSettingsLoader { - sealed trait LoadingIndexError - final case class IndexParsingError(message: String) extends LoadingIndexError - case object IndexUnknownStructure extends LoadingIndexError - case object IndexNotExist extends LoadingIndexError -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala new file mode 100644 index 0000000000..8403c96cb0 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala @@ -0,0 +1,51 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.configuration.loader + +import cats.Show +import monix.eval.Task +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters +import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} + +trait SettingsManager[SETTINGS] { + + def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + fallback: Task[Either[LoadingError, SETTINGS]]): Task[Either[LoadingError, SETTINGS]] + + def loadFromIndex(): Task[Either[LoadingFromIndexError, SETTINGS]] + + def saveToIndex(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] +} +object SettingsManager { + trait LoadingError + + sealed trait LoadingFromIndexError extends LoadingError + object LoadingFromIndexError { + final case class IndexParsingError(message: String) extends LoadingFromIndexError + case object IndexUnknownStructure extends LoadingFromIndexError + case object IndexNotExist extends LoadingFromIndexError + + implicit val show: Show[LoadingFromIndexError] = ??? + } + + sealed trait SavingIndexSettingsError + object SavingIndexSettingsError { + case object CannotSaveSettings extends SavingIndexSettingsError + + implicit val show: Show[SavingIndexSettingsError] = ??? + } +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/utils/RefinedUtils.scala b/core/src/main/scala/tech/beshu/ror/utils/RefinedUtils.scala index 95d310048a..43df378c75 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/RefinedUtils.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/RefinedUtils.scala @@ -22,8 +22,8 @@ import eu.timepit.refined.api.Refined import eu.timepit.refined.numeric.Positive import eu.timepit.refined.types.string.NonEmptyString import io.circe.Decoder -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.ValueLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.* +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.ValueLevelCreationError import tech.beshu.ror.accesscontrol.utils.SyncDecoderCreator import scala.compiletime.error diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 91ddec4bc9..909b599a9a 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -22,7 +22,7 @@ import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.providers.* @@ -41,7 +41,7 @@ trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { envVarsProvider = envVarsProvider, propertiesProvider = propertiesProvider ) - private val factory = new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) + private val factory = new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) protected val ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider = MockLdapConnectionPoolProvider protected val httpClientsFactory: HttpClientsFactory = MockHttpClientsFactory protected val mockProvider: MocksProvider = NoOpMocksProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index c51781a318..3a015fc9a4 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -29,9 +29,9 @@ import tech.beshu.ror.accesscontrol.audit.AuditingTool.Settings.AuditSink.Config import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.AuditCluster.{LocalAuditCluster, RemoteAuditCluster} import tech.beshu.ror.accesscontrol.domain.{AuditCluster, IndexName, RorAuditLoggerName, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.AuditingSettingsCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.{Core, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.AuditingSettingsCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.{Core, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.audit.adapters.DeprecatedAuditLogSerializerAdapter import tech.beshu.ror.audit.instances.{DefaultAuditLogSerializer, QueryAuditLogSerializer} import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} @@ -46,7 +46,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { private def factory(esVersion: EsVersion = defaultEsVersionForTests) = { implicit val systemContext: SystemContext = SystemContext.default - new RawRorConfigBasedCoreFactory(esVersion) + new RawRorSettingsBasedCoreFactory(esVersion) } private val zonedDateTime = ZonedDateTime.of(2019, 1, 1, 0, 1, 59, 0, ZoneId.of("+1")) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index 5c3749e2b3..f9b5dcea28 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -28,9 +28,9 @@ import tech.beshu.ror.accesscontrol.blocks.Block import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{Header, IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} -import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, HttpClientsFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockHttpClientsFactoryWithFixedHttpClient, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* @@ -40,7 +40,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { private val factory: CoreFactory = { implicit val systemContext: SystemContext = SystemContext.default - new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) + new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) } "A RorAclFactory" should { diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 3c5812cd8d..cd60730c00 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvid import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.MockHttpClientsFactory import tech.beshu.ror.syntax.* @@ -387,6 +387,6 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { private val factory: CoreFactory = { implicit val systemContext: SystemContext = SystemContext.default - new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) + new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index 2e8cc87440..52eb436208 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -23,7 +23,7 @@ import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorSettingsIndex, User} -import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.syntax.* @@ -319,7 +319,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { private val factory = { implicit val systemContext: SystemContext = SystemContext.default - new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) + new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/BaseDecoderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/BaseDecoderTest.scala index b650ace46b..0e55e98a09 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/BaseDecoderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/BaseDecoderTest.scala @@ -22,7 +22,7 @@ import cats.implicits.* import io.circe.DecodingFailure import org.scalatest.Inside import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.utils.ADecoder import tech.beshu.ror.accesscontrol.utils.CirceOps.DecodingFailureOps import tech.beshu.ror.utils.TestsUtils diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala index 74b9032414..dd5a16862f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala @@ -21,8 +21,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.GeneralReadonlyrestSettingsError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.GeneralReadonlyrestSettingsError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.GlobalStaticSettingsDecoder import tech.beshu.ror.accesscontrol.utils.{SyncDecoder, SyncDecoderCreator} diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala index 3d8a0d843a..0c8454babe 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex, User, UserIdPatterns} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.definitions.{Definitions, ImpersonationDefinitionsDecoderCreator} import tech.beshu.ror.utils.TestsUtils.* import tech.beshu.ror.utils.uniquelist.UniqueNonEmptyList diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala index 6998a3d73c..15e9dfd482 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala @@ -30,8 +30,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.* import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserGroupsSearchFilterConfig.UserGroupsSearchMode.* import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserSearchFilterConfig.UserIdAttribute import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserSearchFilterConfig.UserIdAttribute.CustomAttribute -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.decoders.definitions.LdapServicesDecoder import tech.beshu.ror.utils.DurationOps.RefinedDurationOps import tech.beshu.ror.utils.RefinedUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala index 14465716b4..c21478c398 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala @@ -19,8 +19,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.variables.transformation.SupportedVariablesFunctions import tech.beshu.ror.accesscontrol.blocks.variables.transformation.domain.Function.{FunctionChain, ReplaceFirst} import tech.beshu.ror.accesscontrol.blocks.variables.transformation.domain.FunctionName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.DefinitionsLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.decoders.definitions.VariableTransformationAliasesDefinitionsDecoder import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala index d159392650..2d5153b03c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala @@ -27,8 +27,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.* import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.{Core, HttpClientsFactory, RawRorConfigBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.{Core, HttpClientsFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.SystemContext import tech.beshu.ror.mocks.MockHttpClientsFactory import tech.beshu.ror.providers.* @@ -48,14 +48,14 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord protected implicit def envVarsProvider: EnvVarsProvider = OsEnvVarsProvider - protected def factory: RawRorConfigBasedCoreFactory = { + protected def factory: RawRorSettingsBasedCoreFactory = { implicit val systemContext: SystemContext = new Environment(envVarsProvider = envVarsProvider) - new RawRorConfigBasedCoreFactory(defaultEsVersionForTests) + new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) } def assertDecodingSuccess(yaml: String, assertion: T => Unit, - aFactory: RawRorConfigBasedCoreFactory = factory, + aFactory: RawRorSettingsBasedCoreFactory = factory, httpClientsFactory: HttpClientsFactory = MockHttpClientsFactory, mocksProvider: MocksProvider = NoOpMocksProvider): Unit = { inside( @@ -78,7 +78,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord def assertDecodingFailure(yaml: String, assertion: NonEmptyList[CoreCreationError] => Unit, - aFactory: RawRorConfigBasedCoreFactory = factory, + aFactory: RawRorSettingsBasedCoreFactory = factory, httpClientsFactory: HttpClientsFactory = MockHttpClientsFactory, mocksProvider: MocksProvider = NoOpMocksProvider): Unit = { inside( diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala index b944587e69..327307dcf2 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.auth import cats.data.NonEmptySet import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.http.ApiKeysRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala index 95c3705580..4809b5c394 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala @@ -19,8 +19,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyHashingRule.HashedCredentials import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyPBKDF2WithHmacSHA512Rule import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala index 9fc8ca11a5..bac56e8148 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala @@ -19,8 +19,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyHashingRule.HashedCredentials import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeySha1Rule import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala index cb6182f532..cf72349917 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala @@ -19,8 +19,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyHashingRule.HashedCredentials import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeySha256Rule import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala index e8ed46326c..79919038c9 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala @@ -19,8 +19,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeyHashingRule.HashedCredentials import tech.beshu.ror.accesscontrol.blocks.rules.auth.AuthKeySha512Rule import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala index bb7d256288..a76815623f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala @@ -21,8 +21,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.{BasicAuthHttpExternalAut import tech.beshu.ror.accesscontrol.blocks.rules.auth.ExternalAuthenticationRule import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.mocks.MockHttpClientsFactoryWithFixedHttpClient import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala index fd2d4c78f1..ab2cc7e269 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala @@ -28,8 +28,8 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.{GroupId, GroupIdPattern} import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.mocks.MockHttpClientsFactoryWithFixedHttpClient import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala index 7e0c77bda8..7670e6f67f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala @@ -34,8 +34,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeMultiResolvableVariable, RuntimeResolvableGroupsLogic} import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.GroupIdLike.{GroupId, GroupIdPattern} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.mocks.{MockRequestContext, MockUserMetadataRequestContext} import tech.beshu.ror.syntax import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala index 8a8b573863..5d8ed33bf7 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} import tech.beshu.ror.mocks.MockHttpClientsFactoryWithFixedHttpClient import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.EnvVarsProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala index 61309d1260..46557840e9 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala @@ -18,8 +18,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.auth import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.LdapAuthRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala index 53de9f6cab..ed049458f2 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala @@ -18,8 +18,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.auth import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.LdapAuthenticationRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala index c34e92e55b..93078c8c3c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala @@ -20,8 +20,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.LdapAuthorizationRule import tech.beshu.ror.accesscontrol.domain.GroupIdLike.{GroupId, GroupIdPattern} import tech.beshu.ror.accesscontrol.domain.{GroupIdLike, GroupsLogic, GroupIds} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala index 1c21561694..b50c7d5514 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala @@ -18,8 +18,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.auth import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.ProxyAuthRule import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* import tech.beshu.ror.utils.uniquelist.UniqueNonEmptyList diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala index 4e8dc6aa26..7c79e8ae1e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthRule import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthRule.Groups import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{GroupIdLike, GroupsLogic, GroupIds} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.EnvVarsProvider import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala index e8486dc8dc..e4e4c891a0 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala @@ -20,8 +20,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.auth.TokenAuthenticationRule import tech.beshu.ror.accesscontrol.blocks.rules.auth.TokenAuthenticationRule.Settings import tech.beshu.ror.accesscontrol.domain.User -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.EnvVarsProvider import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala index 4c14efb2e4..c3e5ac5612 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolva import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, IndexName, RorSettingsIndex, User} import tech.beshu.ror.accesscontrol.factory.GlobalSettings import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala index f45699553e..915d11747c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala @@ -20,8 +20,8 @@ import cats.data.NonEmptySet import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.ActionsRule import tech.beshu.ror.accesscontrol.domain.Action -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala index ec351fd9d0..da0bdca51b 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.DataStreamsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.DataStreamName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala index ca10151ed1..680308a8dd 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala @@ -21,8 +21,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.FieldsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.FieldsRestrictions.{AccessMode, DocumentField} import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{GeneralReadonlyrestSettingsError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{GeneralReadonlyrestSettingsError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala index c585ce99a1..64f257ff41 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala @@ -20,8 +20,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.FilterRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeSingleResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.Filter -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala index 27493408a2..14277acbac 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.indices.IndicesRu import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.ClusterIndexName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala index 4e3c64a533..4de34b0ef4 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.RepositoriesRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.RepositoryName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala index 6e7b4b777f..910673ba43 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala @@ -20,8 +20,8 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.ResponseFieldsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.ResponseFieldsFiltering.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala index 4d3458ccce..3213e38ef1 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.SnapshotsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.SnapshotName -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala index 803f4dc288..232e95504f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.http import cats.data.NonEmptySet import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.http.HeadersAndRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala index 6159d044db..08c41a7a08 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.http import cats.data.NonEmptySet import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.http.HeadersOrRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala index 1c25319e30..80e5c03fcd 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.http import org.scalatest.matchers.should.Matchers.* import squants.information.Bytes import tech.beshu.ror.accesscontrol.blocks.rules.http.MaxBodyLengthRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala index bc96967102..f87a2bc474 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.http import cats.data.NonEmptySet import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.http.MethodsRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.accesscontrol.request.RequestContext.Method import tech.beshu.ror.syntax.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala index 421fa0dcb5..09587beda0 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala @@ -18,8 +18,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.http import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.http.SessionMaxIdleRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.DurationOps.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala index 5f8bb1b2c6..51c324fd38 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala @@ -24,8 +24,8 @@ import tech.beshu.ror.accesscontrol.blocks.BlockContext.CurrentUserMetadataReque import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata import tech.beshu.ror.accesscontrol.blocks.rules.http.UriRegexRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.ToBeResolved -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.syntax.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala index 1687789251..6b859fe298 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.http.XForwardedForRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.Address -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala index 3698a0b6b0..f2b8b06db1 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.kibana import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaAccessRule import tech.beshu.ror.accesscontrol.domain.{IndexName, KibanaAccess, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.unsafeNes diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala index b5ca4ff9bf..846f4fd6e7 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.kibana import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaHideAppsRule import tech.beshu.ror.accesscontrol.domain.KibanaApp.FullNameKibanaApp -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.{kibanaAppRegex, unsafeNes} import tech.beshu.ror.utils.uniquelist.UniqueNonEmptyList diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala index ce9889f382..abf04cf91a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.unit.acl.factory.decoders.rules.kibana import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.rules.kibana.KibanaIndexRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeSingleResolvableVariable.{AlreadyResolved, ToBeResolved} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala index 1e1def09eb..763cf55886 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala @@ -29,8 +29,8 @@ import tech.beshu.ror.accesscontrol.domain.Json.{JsonRepresentation, JsonTree} import tech.beshu.ror.accesscontrol.domain.KibanaAllowedApiPath.AllowedHttpMethod import tech.beshu.ror.accesscontrol.domain.KibanaAllowedApiPath.AllowedHttpMethod.HttpMethod import tech.beshu.ror.accesscontrol.domain.KibanaApp.FullNameKibanaApp -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala index 779c3fc6ec..f25cefd255 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.tranport.HostsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.Address -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala index 4cdfe0db3b..0648ce02c0 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.tranport.LocalHostsRule import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable.{AlreadyResolved, ToBeResolved} import tech.beshu.ror.accesscontrol.domain.Address -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.MalformedValue -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.MalformedValue +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.orders.* import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index da8158ca74..5a549f6afa 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -38,12 +38,12 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} import tech.beshu.ror.accesscontrol.domain.* -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.boot.RorInstance.{IndexConfigInvalidationError, TestConfig} +import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.configuration.RorDependencies.NoOpImpersonationWarningsReader import tech.beshu.ror.configuration.index.SavingIndexConfigError @@ -389,7 +389,7 @@ class ReadonlyRestStartingTests }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) } "there is some config stored in index" should { "load test engine as active" when { @@ -422,10 +422,10 @@ class ReadonlyRestStartingTests }) { case (rorInstance, expirationTimestamp) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -483,8 +483,8 @@ class ReadonlyRestStartingTests }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated( recent = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe ) @@ -512,7 +512,7 @@ class ReadonlyRestStartingTests }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) } } "settings structure is not valid" should { @@ -543,7 +543,7 @@ class ReadonlyRestStartingTests }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) } } "settings structure is valid, rule is malformed and cannot start engine" should { @@ -573,8 +573,8 @@ class ReadonlyRestStartingTests readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(5 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated( recent = testConfigMalformed, configuredTtl = (100 seconds).toRefinedPositiveUnsafe ) @@ -604,7 +604,7 @@ class ReadonlyRestStartingTests }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -622,15 +622,15 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestConfigEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult.value shouldBe a[TestConfig.Present] + testEngineReloadResult.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestConfig.Present] - Option(testEngineConfig.asInstanceOf[TestConfig.Present]).map(i => (i.rawConfig, i.configuredTtl.value)) should be { + val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfig shouldBe a[TestSettings.Present] + Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { (testConfig1, 1 minute).some } } @@ -655,7 +655,7 @@ class ReadonlyRestStartingTests (readonlyRest, mockedIndexJsonContentManager) }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -673,34 +673,34 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult1stAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestConfig.Present] - Option(testEngineConfig.asInstanceOf[TestConfig.Present]).map(i => (i.rawConfig, i.configuredTtl.value)) should be { + val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfig shouldBe a[TestSettings.Present] + Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { (testConfig1, 1 minute).some } - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestConfig.Present].validTo + val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult2ndAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestConfig.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestConfig.Present]).map(i => (i.rawConfig, i.configuredTtl.value)) should be { + val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfigAfterReload shouldBe a[TestSettings.Present] + Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { (testConfig1, 1 minute).some } - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestConfig.Present].validTo + val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(true) } @@ -724,7 +724,7 @@ class ReadonlyRestStartingTests (readonlyRest, mockedIndexJsonContentManager) }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -742,18 +742,18 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig1, (10 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (10 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult1stAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestConfig.Present] - Option(testEngineConfig.asInstanceOf[TestConfig.Present]) - .map(i => (i.rawConfig, i.configuredTtl.value)) should be((testConfig1, 10 minute).some) + val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfig shouldBe a[TestSettings.Present] + Option(testEngineConfig.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig1, 10 minute).some) - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestConfig.Present].validTo + val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo (mockedIndexJsonContentManager.saveContent _) .expects( @@ -771,18 +771,18 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig1, (5 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (5 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult2ndAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestConfig.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestConfig.Present]) - .map(i => (i.rawConfig, i.configuredTtl.value)) should be((testConfig1, 5 minute).some) + val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfigAfterReload shouldBe a[TestSettings.Present] + Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig1, 5 minute).some) - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestConfig.Present].validTo + val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(false) } @@ -808,7 +808,7 @@ class ReadonlyRestStartingTests (readonlyRest, mockedIndexJsonContentManager) }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -826,19 +826,19 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult1stAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestConfig.Present] - Option(testEngineConfig.asInstanceOf[TestConfig.Present]).map(i => (i.rawConfig, i.configuredTtl.value)) should be { + val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfig shouldBe a[TestSettings.Present] + Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { (testConfig1, 1 minute).some } - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestConfig.Present].validTo + val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo (mockedIndexJsonContentManager.saveContent _) .expects( @@ -856,18 +856,18 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestConfigEngine(testConfig2, (2 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig2, (2 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult2ndAttempt.value shouldBe a[TestConfig.Present] + testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestConfig.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestConfig.Present]) - .map(i => (i.rawConfig, i.configuredTtl.value)) should be((testConfig2, 2 minutes).some) + val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testEngineConfigAfterReload shouldBe a[TestSettings.Present] + Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig2, 2 minutes).some) - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestConfig.Present].validTo + val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(true) } @@ -907,16 +907,16 @@ class ReadonlyRestStartingTests ))) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) Task.sleep(5 seconds).runSyncUnsafe() rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -950,10 +950,10 @@ class ReadonlyRestStartingTests val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -976,10 +976,10 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (200 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 ) @@ -1014,10 +1014,10 @@ class ReadonlyRestStartingTests (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -1040,10 +1040,10 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 ) @@ -1078,10 +1078,10 @@ class ReadonlyRestStartingTests (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -1104,8 +1104,8 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated( recent = testConfig2, configuredTtl = (200 seconds).toRefinedPositiveUnsafe ) @@ -1133,7 +1133,7 @@ class ReadonlyRestStartingTests }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -1151,17 +1151,17 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestConfigEngine(testConfig1, (3 seconds).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (3 seconds).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult.value shouldBe a[TestConfig.Present] + testEngineReloadResult.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] Task.sleep(5 seconds).runSyncUnsafe() rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated(testConfig1, (3 seconds).toRefinedPositiveUnsafe) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated(testConfig1, (3 seconds).toRefinedPositiveUnsafe) ) } } @@ -1185,7 +1185,7 @@ class ReadonlyRestStartingTests (readonlyRest, mockedIndexJsonContentManager) }) { case (rorInstance, mockedIndexJsonContentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be(TestConfig.NotSet) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) (mockedIndexJsonContentManager.saveContent _) .expects( @@ -1203,12 +1203,12 @@ class ReadonlyRestStartingTests .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestConfigEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - testEngineReloadResult.value shouldBe a[TestConfig.Present] + testEngineReloadResult.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() shouldBe a[TestConfig.Present] + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() shouldBe a[TestSettings.Present] (mockedIndexJsonContentManager.saveContent _) .expects( @@ -1225,11 +1225,11 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.now(Right(()))) - rorInstance.invalidateTestConfigEngine()(newRequestId()).runSyncUnsafe() should be(Right(())) + rorInstance.invalidateTestSettingsEngine()(newRequestId()).runSyncUnsafe() should be(Right(())) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated(recent = testConfig1, configuredTtl = (1 minute).toRefinedPositiveUnsafe) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated(recent = testConfig1, configuredTtl = (1 minute).toRefinedPositiveUnsafe) ) } "should return error for invalidation" when { @@ -1261,10 +1261,10 @@ class ReadonlyRestStartingTests (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Present( + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Present( dependencies = RorDependencies.noOp, - rawConfig = testConfig1, + rawSettings = testConfig1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -1284,13 +1284,13 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.now(Left(CannotWriteToIndex))) - rorInstance.invalidateTestConfigEngine()(newRequestId()).runSyncUnsafe() should be( - Left(IndexConfigInvalidationError.IndexConfigSavingError(SavingIndexConfigError.CannotSaveConfig)) + rorInstance.invalidateTestSettingsEngine()(newRequestId()).runSyncUnsafe() should be( + Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingIndexConfigError.CannotSaveConfig)) ) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) - rorInstance.currentTestConfig()(newRequestId()).runSyncUnsafe() should be( - TestConfig.Invalidated(testConfig1, (100 seconds).toRefinedPositiveUnsafe) + rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( + TestSettings.Invalidated(testConfig1, (100 seconds).toRefinedPositiveUnsafe) ) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index b618b5111f..a7cc32e610 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} -import tech.beshu.ror.boot.RorInstance.TestConfig +import tech.beshu.ror.boot.RorInstance.TestSettings import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} @@ -129,10 +129,10 @@ class RorIndexTest extends AnyWordSpec val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestConfigEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - forceReloadingResult.value shouldBe a[TestConfig.Present] + forceReloadingResult.value shouldBe a[TestSettings.Present] } } "custom index is defined in config" should { @@ -205,10 +205,10 @@ class RorIndexTest extends AnyWordSpec val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestConfigEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() - forceReloadingResult.value shouldBe a[TestConfig.Present] + forceReloadingResult.value shouldBe a[TestSettings.Present] } } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..03e9a93a3c 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -46,7 +46,7 @@ class RRAdminActionHandler extends Logging { } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..ec28c3351d 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainRorSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainRorSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainRorSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -39,18 +39,18 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload + MainRorSettingsApi.MainSettingsRequest.Type.ForceReload case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig + MainRorSettingsApi.MainSettingsRequest.Type.ProvideFileSettings case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig + MainRorSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + MainRorSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainRorSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..e0e9061ba5 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainRorSettingsApi +import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainRorSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainRorSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadConfig: MainSettingsResponse.ForceReloadMainSettings => forceReloadConfig match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexConfig: MainSettingsResponse.ProvideIndexMainSettings => provideIndexConfig match { + case ProvideIndexMainSettings.MainSettings(rawConfig) => addResponseJson(builder, response.status, rawConfig) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileConfig: MainSettingsResponse.ProvideFileMainSettings => provideFileConfig match { + case ProvideFileMainSettings.MainSettings(rawConfig) => addResponseJson(builder, response.status, rawConfig) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexConfig: MainSettingsResponse.UpdateIndexMainSettings => updateIndexConfig match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala index aa8bb31e67..06a4c37fec 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -46,7 +46,7 @@ class RRTestConfigActionHandler extends Logging { } } - private def handle(result: Either[Throwable, TestConfigResponse], + private def handle(result: Either[Throwable, TestSettingsResponse], listener: ActionListener[RRTestConfigResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRTestConfigActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala index d4574bf654..cbe25cf2fd 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestRorSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, +class RRTestConfigRequest(testConfigApiRequest: TestRorSettingsApi.TestSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = + def getTestConfigRequest: RorApiRequest[TestRorSettingsApi.TestSettingsRequest] = RorApiRequest(testConfigApiRequest, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") @@ -41,18 +41,18 @@ object RRTestConfigRequest { def createFrom(request: RestRequest): RRTestConfigRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig + TestRorSettingsApi.TestSettingsRequest.Type.ProvideTestSettings case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig + TestRorSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + TestRorSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestRorSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + TestRorSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala index d2c63676b7..740ecc7259 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala @@ -21,28 +21,28 @@ import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestRorSettingsApi +import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestConfigResponse(response: TestRorSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideConfigResponse: ProvideTestSettings => provideConfigResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentConfigJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedConfigJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateConfigResponse: UpdateTestSettings => updateConfigResponse match { + case res: UpdateTestSettings.SuccessResponse => updateConfigSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateConfigResponse: InvalidateTestSettings => invalidateConfigResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,7 +75,7 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentConfigJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) @@ -85,7 +85,7 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) @@ -94,7 +94,7 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) From 1261b0b5ba72f6ec17cc87d8b4e9d282e982e098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 11 Jul 2025 19:33:26 +0200 Subject: [PATCH 016/103] refactoring --- .../boot/engines/BaseReloadableEngine.scala | 302 +++++++++--------- .../MainSettingsBasedReloadableEngine.scala | 38 +-- .../{ConfigHash.scala => SettingsHash.scala} | 8 +- .../TestSettingsBasedReloadableEngine.scala | 114 +++---- .../EsConfigBasedRorSettings.scala | 18 +- ...nfiguration.scala => RorSslSettings.scala} | 0 ...ServiceBasedIndexMainSettingsManager.scala | 4 +- ...ServiceBasedIndexTestSettingsManager.scala | 4 +- .../loader/FileRorSettingsLoader.scala | 10 +- .../main/scala/tech/beshu/ror/implicits.scala | 10 +- 10 files changed, 254 insertions(+), 254 deletions(-) rename core/src/main/scala/tech/beshu/ror/boot/engines/{ConfigHash.scala => SettingsHash.scala} (75%) rename core/src/main/scala/tech/beshu/ror/configuration/{SslConfiguration.scala => RorSslSettings.scala} (100%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index a8f31ae74c..effa4f1faf 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -30,7 +30,7 @@ import tech.beshu.ror.boot.ReadonlyRest.Engine import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet -import tech.beshu.ror.boot.engines.ConfigHash.* +import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.* @@ -52,19 +52,19 @@ private[engines] abstract class BaseReloadableEngine(val name: String, private val currentEngine: Atomic[EngineState] = AtomicAny[EngineState]( initialEngine match { - case InitialEngine.Configured(engine, config, expirationConfig) => - logger.info(s"ROR ${name.show} engine (id=${config.hashString().show}) was initiated (${engine.core.accessControl.description.show}).") - stateFromInitial(EngineWithConfig(engine, config, expirationConfig))(RequestId(systemContext.uuidProvider.random.toString)) + case InitialEngine.Configured(engine, settings, expiration) => + logger.info(s"ROR ${name.show} engine (id=${settings.hashString().show}) was initiated (${engine.core.accessControl.description.show}).") + stateFromInitial(EngineWithSettings(engine, settings, expiration))(RequestId(systemContext.uuidProvider.random.toString)) case InitialEngine.NotConfigured => - EngineState.NotStartedYet(recentConfig = None, recentExpirationConfig = None) - case InitialEngine.Invalidated(config, expirationConfig) => - EngineState.NotStartedYet(recentConfig = Some(config), recentExpirationConfig = Some(expirationConfig)) + EngineState.NotStartedYet(recentSettings = None, recentExpiration = None) + case InitialEngine.Invalidated(settings, expiration) => + EngineState.NotStartedYet(recentSettings = Some(settings), recentExpiration = Some(expiration)) } ) def engine: Option[Engine] = currentEngine.get() match { case EngineState.NotStartedYet(_, _) => None - case EngineState.Working(engineWithConfig, _) => Some(engineWithConfig.engine) + case EngineState.Working(engineWithSetting, _) => Some(engineWithSetting.engine) case EngineState.Stopped => None } @@ -76,8 +76,8 @@ private[engines] abstract class BaseReloadableEngine(val name: String, _ <- Task.delay { state match { case EngineState.NotStartedYet(_, _) => - case working@EngineState.Working(engineWithConfig, _) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithConfig.config.hashString().show}) will be stopped ...") + case working@EngineState.Working(engineWithSetting, _) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithSetting.settings.hashString().show}) will be stopped ...") stopNow(working) case EngineState.Stopped => } @@ -86,29 +86,29 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - protected def invalidate(keepPreviousConfiguration: Boolean) + protected def invalidate(keepPreviousSettings: Boolean) (implicit requestId: RequestId): Task[Option[InvalidationResult]] = { Task.delay { val invalidationTimestamp = systemContext.clock.instant() val previous = currentEngine.getAndTransform { case notStarted: EngineState.NotStartedYet => - if (keepPreviousConfiguration) { + if (keepPreviousSettings) { notStarted - } else { - EngineState.NotStartedYet(recentConfig = None, recentExpirationConfig = None) + } else { + EngineState.NotStartedYet(recentSettings = None, recentExpiration = None) } - case oldWorkingEngine@EngineState.Working(engineWithConfig, _) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithConfig.config.hashString().show}) will be invalidated ...") + case oldWorkingEngine@EngineState.Working(engineWithSetting, _) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithSetting.settings.hashString().show}) will be invalidated ...") stopEarly(oldWorkingEngine) - if (keepPreviousConfiguration) { + if (keepPreviousSettings) { EngineState.NotStartedYet( - recentConfig = Some(engineWithConfig.config), - recentExpirationConfig = engineWithConfig.expirationConfig.map { - recentConfig => recentConfig.copy(validTo = invalidationTimestamp) + recentSettings = Some(engineWithSetting.settings), + recentExpiration = engineWithSetting.expiration.map { + recentSettings => recentSettings.copy(validTo = invalidationTimestamp) } ) } else { - EngineState.NotStartedYet(recentConfig = None, recentExpirationConfig = None) + EngineState.NotStartedYet(recentSettings = None, recentExpiration = None) } case EngineState.Stopped => EngineState.Stopped @@ -116,9 +116,9 @@ private[engines] abstract class BaseReloadableEngine(val name: String, previous match { case _: EngineState.NotStartedYet => None - case EngineState.Working(engineWithConfig, _) => - engineWithConfig.expirationConfig.map(expirationConfig => - InvalidationResult(engineWithConfig.config, expirationConfig.copy(validTo = invalidationTimestamp)) + case EngineState.Working(engineWithSetting, _) => + engineWithSetting.expiration.map(expiration => + InvalidationResult(engineWithSetting.settings, expiration.copy(validTo = invalidationTimestamp)) ) case EngineState.Stopped => None } @@ -132,31 +132,31 @@ private[engines] abstract class BaseReloadableEngine(val name: String, reloadEngineWithoutTtl(rorSettings) } - protected def reloadEngine(newConfig: RawRorSettings, - newConfigEngineTtl: PositiveFiniteDuration) + protected def reloadEngine(newSettings: RawRorSettings, + newSettingsEngineTtl: PositiveFiniteDuration) (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { - reloadEngineWithConfiguredTtl(newConfig, UpdatedConfigExpiration.ByTtl(newConfigEngineTtl)) + reloadEngineWithConfiguredTtl(newSettings, UpdatedExpiration.ByTtl(newSettingsEngineTtl)) } - protected def reloadEngine(newConfig: RawRorSettings, - newConfigExpirationTime: Instant, + protected def reloadEngine(newSettings: RawRorSettings, + newSettingsExpirationTime: Instant, configuredTtl: PositiveFiniteDuration) (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { - isStillValid(newConfigExpirationTime) match { + isStillValid(newSettingsExpirationTime) match { case RemainingEngineTime.Valid(_) => - reloadEngineWithConfiguredTtl(newConfig, UpdatedConfigExpiration.ToTime(newConfigExpirationTime, configuredTtl)) + reloadEngineWithConfiguredTtl(newSettings, UpdatedExpiration.ToTime(newSettingsExpirationTime, configuredTtl)) .map(_ => ()) case RemainingEngineTime.Expired => EitherT.right { Task.delay { - val newExpirationConfig = EngineExpirationConfig(ttl = configuredTtl, validTo = newConfigExpirationTime) + val newExpiration = EngineExpiration(ttl = configuredTtl, validTo = newSettingsExpirationTime) currentEngine.transform { case _: EngineState.NotStartedYet => - NotStartedYet(recentConfig = Some(newConfig), recentExpirationConfig = Some(newExpirationConfig)) + NotStartedYet(recentSettings = Some(newSettings), recentExpiration = Some(newExpiration)) case working: EngineState.Working => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${working.engineWithConfig.config.hashString().show}) will be invalidated ...") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${working.engineWithSetting.settings.hashString().show}) will be invalidated ...") stopEarly(working) - NotStartedYet(recentConfig = Some(newConfig), recentExpirationConfig = Some(newExpirationConfig)) + NotStartedYet(recentSettings = Some(newSettings), recentExpiration = Some(newExpiration)) case EngineState.Stopped => EngineState.Stopped } @@ -165,22 +165,22 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def reloadEngineWithConfiguredTtl(newConfig: RawRorSettings, - expiration: UpdatedConfigExpiration) + private def reloadEngineWithConfiguredTtl(newSettings: RawRorSettings, + expiration: UpdatedExpiration) (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { for { - engineUpdateType <- checkUpdateType(newConfig, expiration) - expirationConfig <- engineUpdateType match { - case EngineUpdateType.UpdateConfig => - runReload(newConfig, Some(expiration)).map { engine => - ReloadResult(engine.engine, engine.expirationConfig.get) + engineUpdateType <- checkUpdateType(newSettings, expiration) + expiration <- engineUpdateType match { + case EngineUpdateType.UpdateSettings => + runReload(newSettings, Some(expiration)).map { engine => + ReloadResult(engine.engine, engine.expiration.get) } - case EngineUpdateType.UpdateConfigTtl => - updateEngineExpirationConfig(expiration) - case EngineUpdateType.ConfigAndTtlUpToDate(engine, expirationConfig) => - EitherT.right[RawSettingsReloadError](Task.now(ReloadResult(engine, expirationConfig))) + case EngineUpdateType.UpdateSettingsTtl => + updateEngineExpiration(expiration) + case EngineUpdateType.SettingsAndTtlUpToDate(engine, expiration) => + EitherT.right[RawSettingsReloadError](Task.now(ReloadResult(engine, expiration))) } - } yield expirationConfig + } yield expiration } private def reloadEngineWithoutTtl(rorSettings: RawRorSettings) @@ -192,25 +192,25 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def runReload(rorSettings: RawRorSettings, - configExpiration: Option[UpdatedConfigExpiration]) - (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, EngineWithConfig] = { + expiration: Option[UpdatedExpiration]) + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, EngineWithSettings] = { for { - newEngineWithConfig <- reloadWith(rorSettings, configExpiration) - _ <- replaceCurrentEngine(newEngineWithConfig) - } yield newEngineWithConfig + newEngineWithSettings <- reloadWith(rorSettings, expiration) + _ <- replaceCurrentEngine(newEngineWithSettings) + } yield newEngineWithSettings } - private def checkUpdateType(newConfig: RawRorSettings, - newConfigExpiration: UpdatedConfigExpiration): EitherT[Task, RawSettingsReloadError, EngineUpdateType] = { + private def checkUpdateType(newSettings: RawRorSettings, + newExpiration: UpdatedExpiration): EitherT[Task, RawSettingsReloadError, EngineUpdateType] = { EitherT { Task.delay { currentEngine.get() match { case EngineState.NotStartedYet(_, _) => - Right(EngineUpdateType.UpdateConfig) - case EngineState.Working(EngineWithConfig(_, currentConfig, _), _) if currentConfig != newConfig => - Right(EngineUpdateType.UpdateConfig) - case EngineState.Working(EngineWithConfig(engine, _, engineExpirationConfig), _) => - checkIfExpirationConfigHasChanged(engine, newConfigExpiration, engineExpirationConfig) + Right(EngineUpdateType.UpdateSettings) + case EngineState.Working(EngineWithSettings(_, currentSettings, _), _) if currentSettings != newSettings => + Right(EngineUpdateType.UpdateSettings) + case EngineState.Working(EngineWithSettings(engine, _, engineExpiration), _) => + checkIfExpirationHasChanged(engine, newExpiration, engineExpiration) case EngineState.Stopped => Left(RawSettingsReloadError.RorInstanceStopped) } @@ -218,32 +218,32 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def checkIfExpirationConfigHasChanged(engine: Engine, - newConfigExpiration: UpdatedConfigExpiration, - engineExpirationConfig: Option[EngineExpirationConfig]) = { - newConfigExpiration match { - case UpdatedConfigExpiration.ByTtl(_) => - Right(EngineUpdateType.UpdateConfigTtl) - case UpdatedConfigExpiration.ToTime(validTo, configuredTtl) => - val providedExpirationConfig = EngineExpirationConfig(configuredTtl, validTo) - if (engineExpirationConfig.contains(providedExpirationConfig)) { - Right(EngineUpdateType.ConfigAndTtlUpToDate(engine, providedExpirationConfig)) + private def checkIfExpirationHasChanged(engine: Engine, + newExpiration: UpdatedExpiration, + engineExpiration: Option[EngineExpiration]) = { + newExpiration match { + case UpdatedExpiration.ByTtl(_) => + Right(EngineUpdateType.UpdateSettingsTtl) + case UpdatedExpiration.ToTime(validTo, configuredTtl) => + val providedExpiration = EngineExpiration(configuredTtl, validTo) + if (engineExpiration.contains(providedExpiration)) { + Right(EngineUpdateType.SettingsAndTtlUpToDate(engine, providedExpiration)) } else { - Right(EngineUpdateType.UpdateConfigTtl) + Right(EngineUpdateType.UpdateSettingsTtl) } } } - private def canBeReloaded(newConfig: RawRorSettings): EitherT[Task, RawSettingsReloadError, Unit] = { + private def canBeReloaded(newSettings: RawRorSettings): EitherT[Task, RawSettingsReloadError, Unit] = { EitherT { Task.delay { currentEngine.get() match { case EngineState.NotStartedYet(_, _) => Right(()) - case EngineState.Working(EngineWithConfig(_, currentConfig, _), _) if currentConfig != newConfig => + case EngineState.Working(EngineWithSettings(_, currentSettings, _), _) if currentSettings != newSettings => Right(()) - case EngineState.Working(EngineWithConfig(_, currentConfig, _), _) => - Left(RawSettingsReloadError.SettingsUpToDate(currentConfig)) + case EngineState.Working(EngineWithSettings(_, currentSettings, _), _) => + Left(RawSettingsReloadError.SettingsUpToDate(currentSettings)) case EngineState.Stopped => Left(RawSettingsReloadError.RorInstanceStopped) } @@ -252,47 +252,47 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def reloadWith(rorSettings: RawRorSettings, - configExpiration: Option[UpdatedConfigExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithConfig] = EitherT { + expiration: Option[UpdatedExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithSettings] = EitherT { tryToLoadRorCore(rorSettings) .map(_ .map { engine => - EngineWithConfig( + EngineWithSettings( engine = engine, - config = rorSettings, - expirationConfig = configExpiration.map(engineExpirationConfig) + settings = rorSettings, + expiration = expiration.map(engineExpiration) ) } .leftMap(RawSettingsReloadError.ReloadingFailed.apply) ) } - private def engineExpirationConfig(configExpiration: UpdatedConfigExpiration) = { - configExpiration match { - case UpdatedConfigExpiration.ByTtl(ttl) => - EngineExpirationConfig(ttl = ttl, validTo = systemContext.clock.instant().plusMillis(ttl.value.toMillis)) - case UpdatedConfigExpiration.ToTime(validTo, configuredTtl) => - EngineExpirationConfig(ttl = configuredTtl, validTo = validTo) + private def engineExpiration(expiration: UpdatedExpiration) = { + expiration match { + case UpdatedExpiration.ByTtl(ttl) => + EngineExpiration(ttl = ttl, validTo = systemContext.clock.instant().plusMillis(ttl.value.toMillis)) + case UpdatedExpiration.ToTime(validTo, configuredTtl) => + EngineExpiration(ttl = configuredTtl, validTo = validTo) } } private def tryToLoadRorCore(rorSettings: RawRorSettings) = boot.loadRorEngine(rorSettings, esConfig) - private def replaceCurrentEngine(newEngineWithConfig: EngineWithConfig) + private def replaceCurrentEngine(newEngineWithSettings: EngineWithSettings) (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { EitherT { Task.delay { val oldEngineState = currentEngine.getAndTransform { case _: EngineState.NotStartedYet => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${newEngineWithConfig.config.hashString().show}) is going to be used ...") - workingStateFrom(newEngineWithConfig) + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${newEngineWithSettings.settings.hashString().show}) is going to be used ...") + workingStateFrom(newEngineWithSettings) case oldWorkingEngine@EngineState.Working(_, _) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldWorkingEngine.engineWithConfig.config.hashString().show}) will be replaced with engine (id=${newEngineWithConfig.config.hashString().show}) ...") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldWorkingEngine.engineWithSetting.settings.hashString().show}) will be replaced with engine (id=${newEngineWithSettings.settings.hashString().show}) ...") stopEarly(oldWorkingEngine) - workingStateFrom(newEngineWithConfig) + workingStateFrom(newEngineWithSettings) case EngineState.Stopped => - logger.warn(s"[${requestId.show}] ROR ${name.show} engine (id=${newEngineWithConfig.config.hashString().show}) cannot be used because the ROR is already stopped!") - newEngineWithConfig.engine.shutdown() + logger.warn(s"[${requestId.show}] ROR ${name.show} engine (id=${newEngineWithSettings.settings.hashString().show}) cannot be used because the ROR is already stopped!") + newEngineWithSettings.engine.shutdown() EngineState.Stopped } oldEngineState match { @@ -304,83 +304,83 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def workingStateFrom(engineWithConfig: EngineWithConfig) + private def workingStateFrom(engineWithSetting: EngineWithSettings) (implicit requestId: RequestId) = EngineState.Working( - engineWithConfig, - engineWithConfig.expirationConfig.map(_.ttl).map { ttl => + engineWithSetting, + engineWithSetting.expiration.map(_.ttl).map { ttl => scheduler.scheduleOnce(ttl.value) { - stopEngine(engineWithConfig) + stopEngine(engineWithSetting) } } ) - private def stopEngine(engineWithConfig: EngineWithConfig) + private def stopEngine(engineWithSetting: EngineWithSettings) (implicit requestId: RequestId): Unit = { - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithConfig.config.hashString().show}) is being stopped after TTL were reached ...") - stop(engineWithConfig) + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithSetting.settings.hashString().show}) is being stopped after TTL were reached ...") + stop(engineWithSetting) currentEngine.transform { case EngineState.NotStartedYet(_, _) => EngineState.NotStartedYet( - recentConfig = Some(engineWithConfig.config), - recentExpirationConfig = engineWithConfig.expirationConfig + recentSettings = Some(engineWithSetting.settings), + recentExpiration = engineWithSetting.expiration ) case EngineState.Working(_, _) => EngineState.NotStartedYet( - recentConfig = Some(engineWithConfig.config), - recentExpirationConfig = engineWithConfig.expirationConfig + recentSettings = Some(engineWithSetting.settings), + recentExpiration = engineWithSetting.expiration ) case EngineState.Stopped => EngineState.Stopped } } - private def stateFromInitial(engineWithConfig: EngineWithConfig) + private def stateFromInitial(engineWithSetting: EngineWithSettings) (implicit requestId: RequestId): EngineState = { - engineWithConfig.expirationConfig match { - case Some(expirationConfig) => - isStillValid(expirationConfig.validTo) match { + engineWithSetting.expiration match { + case Some(expiration) => + isStillValid(expiration.validTo) match { case RemainingEngineTime.Valid(remainingEngineTtl) => EngineState.Working( - engineWithConfig, + engineWithSetting, scheduler .scheduleOnce(remainingEngineTtl.value) { - stopEngine(engineWithConfig) + stopEngine(engineWithSetting) } .some ) case RemainingEngineTime.Expired => - stop(engineWithConfig) + stop(engineWithSetting) EngineState.NotStartedYet( - recentConfig = Some(engineWithConfig.config), - recentExpirationConfig = engineWithConfig.expirationConfig + recentSettings = Some(engineWithSetting.settings), + recentExpiration = engineWithSetting.expiration ) } case None => - EngineState.Working(engineWithConfig, scheduledShutdownJob = None) + EngineState.Working(engineWithSetting, scheduledShutdownJob = None) } } - private def updateEngineExpirationConfig(configExpiration: UpdatedConfigExpiration) - (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { + private def updateEngineExpiration(expiration: UpdatedExpiration) + (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, ReloadResult] = { EitherT { Task.delay { val newEngineState = currentEngine.transformAndGet { - case EngineState.NotStartedYet(recentConfig, recentExpirationConfig) => - EngineState.NotStartedYet(recentConfig, recentExpirationConfig) - case EngineState.Working(engineWithConfig, scheduledShutdownJob) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithConfig.config.hashString().show}) is being updated with new TTL ...") + case EngineState.NotStartedYet(recentSettings, recentExpiration) => + EngineState.NotStartedYet(recentSettings, recentExpiration) + case EngineState.Working(engineWithSetting, scheduledShutdownJob) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithSetting.settings.hashString().show}) is being updated with new TTL ...") scheduledShutdownJob.foreach(_.cancel()) - val engineWithNewExpirationConfig = engineWithConfig.copy(expirationConfig = Some(engineExpirationConfig(configExpiration))) - workingStateFrom(engineWithNewExpirationConfig) + val engineWithNewExpiration = engineWithSetting.copy(expiration = Some(engineExpiration(expiration))) + workingStateFrom(engineWithNewExpiration) case EngineState.Stopped => EngineState.Stopped } newEngineState match { case _: EngineState.NotStartedYet => Left(RawSettingsReloadError.ReloadingFailed(ReadonlyRest.StartingFailure("Cannot update engine TTL because engine was invalidated"))) - case EngineState.Working(engineWithConfig, _) => - Right(ReloadResult(engineWithConfig.engine, engineWithConfig.expirationConfig.get)) + case EngineState.Working(engineWithSetting, _) => + Right(ReloadResult(engineWithSetting.engine, engineWithSetting.expiration.get)) case EngineState.Stopped => Left(RawSettingsReloadError.RorInstanceStopped) } @@ -392,22 +392,22 @@ private[engines] abstract class BaseReloadableEngine(val name: String, (implicit requestId: RequestId): Unit = { engineState.scheduledShutdownJob.foreach(_.cancel()) scheduler.scheduleOnce(delayOfOldEngineShutdown) { - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineState.engineWithConfig.config.hashString().show}) is being stopped early ...") - stop(engineState.engineWithConfig) + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineState.engineWithSetting.settings.hashString().show}) is being stopped early ...") + stop(engineState.engineWithSetting) } } private def stopNow(engineState: EngineState.Working) (implicit requestId: RequestId): Unit = { - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineState.engineWithConfig.config.hashString().show}) is being stopped now ...") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineState.engineWithSetting.settings.hashString().show}) is being stopped now ...") engineState.scheduledShutdownJob.foreach(_.cancel()) - stop(engineState.engineWithConfig) + stop(engineState.engineWithSetting) } - private def stop(engineWithConfig: EngineWithConfig) + private def stop(engineWithSetting: EngineWithSettings) (implicit requestId: RequestId): Unit = { - engineWithConfig.engine.shutdown() - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithConfig.config.hashString().show}) stopped!") + engineWithSetting.engine.shutdown() + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${engineWithSetting.settings.hashString().show}) stopped!") } private def isStillValid(validTo: Instant) = { @@ -426,33 +426,33 @@ object BaseReloadableEngine { private[engines] object InitialEngine { case object NotConfigured extends InitialEngine final case class Configured(engine: Engine, - config: RawRorSettings, - expirationConfig: Option[EngineExpirationConfig]) extends InitialEngine - final case class Invalidated(config: RawRorSettings, - expirationConfig: EngineExpirationConfig) extends InitialEngine + settings: RawRorSettings, + expiration: Option[EngineExpiration]) extends InitialEngine + final case class Invalidated(settings: RawRorSettings, + expiration: EngineExpiration) extends InitialEngine } private[engines] final case class ReloadResult(engine: Engine, - expirationConfig: EngineExpirationConfig) + expiration: EngineExpiration) - private[engines] final case class InvalidationResult(config: RawRorSettings, - expirationConfig: EngineExpirationConfig) + private[engines] final case class InvalidationResult(settings: RawRorSettings, + expiration: EngineExpiration) - private[engines] final case class EngineExpirationConfig(ttl: PositiveFiniteDuration, - validTo: Instant) + private[engines] final case class EngineExpiration(ttl: PositiveFiniteDuration, + validTo: Instant) - private[engines] final case class EngineWithConfig(engine: Engine, - config: RawRorSettings, - expirationConfig: Option[EngineExpirationConfig]) + private[engines] final case class EngineWithSettings(engine: Engine, + settings: RawRorSettings, + expiration: Option[EngineExpiration]) private[engines] sealed trait EngineState private[engines] object EngineState { - final case class NotStartedYet(recentConfig: Option[RawRorSettings], - recentExpirationConfig: Option[EngineExpirationConfig]) + final case class NotStartedYet(recentSettings: Option[RawRorSettings], + recentExpiration: Option[EngineExpiration]) extends EngineState - final case class Working(engineWithConfig: EngineWithConfig, + final case class Working(engineWithSetting: EngineWithSettings, scheduledShutdownJob: Option[Cancelable]) extends EngineState @@ -460,11 +460,11 @@ object BaseReloadableEngine { extends EngineState } - private[BaseReloadableEngine] sealed trait UpdatedConfigExpiration - private[BaseReloadableEngine] object UpdatedConfigExpiration { - final case class ByTtl(finiteDuration: PositiveFiniteDuration) extends UpdatedConfigExpiration + private[BaseReloadableEngine] sealed trait UpdatedExpiration + private[BaseReloadableEngine] object UpdatedExpiration { + final case class ByTtl(finiteDuration: PositiveFiniteDuration) extends UpdatedExpiration final case class ToTime(validTo: Instant, - configuredTtl: PositiveFiniteDuration) extends UpdatedConfigExpiration + configuredTtl: PositiveFiniteDuration) extends UpdatedExpiration } private[BaseReloadableEngine] sealed trait RemainingEngineTime @@ -475,9 +475,9 @@ object BaseReloadableEngine { private[BaseReloadableEngine] sealed trait EngineUpdateType private[BaseReloadableEngine] object EngineUpdateType { - case object UpdateConfig extends EngineUpdateType - case object UpdateConfigTtl extends EngineUpdateType - final case class ConfigAndTtlUpToDate(engine: Engine, expirationConfig: EngineExpirationConfig) extends EngineUpdateType + case object UpdateSettings extends EngineUpdateType + case object UpdateSettingsTtl extends EngineUpdateType + final case class SettingsAndTtlUpToDate(engine: Engine, expiration: EngineExpiration) extends EngineUpdateType } private[BaseReloadableEngine] val delayOfOldEngineShutdown = 10 seconds diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 9ab17cb232..13f466633d 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -28,10 +28,10 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine -import tech.beshu.ror.boot.engines.ConfigHash.* -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.loader.RorMainSettingsManager import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value @@ -46,29 +46,29 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, name = "main", boot = boot, esConfig = esConfig, - initialEngine = InitialEngine.Configured(engine = initialEngine._1, config = initialEngine._2, expirationConfig = None), + initialEngine = InitialEngine.Configured(engine = initialEngine._1, settings = initialEngine._2, expiration = None), reloadInProgress = reloadInProgress ) { - def forceReloadAndSave(config: RawRorSettings) + def forceReloadAndSave(settings: RawRorSettings) (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, Unit]] = { for { - _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${config.hashString()}) ...")) + _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${settings.hashString()}) ...")) reloadResult <- reloadInProgress.withPermit { value { for { - _ <- reloadEngine(config).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) - _ <- saveConfig(config) + _ <- reloadEngine(settings).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) + _ <- saveSettings(settings) } yield () } } _ <- Task.delay(reloadResult match { case Right(_) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) settings reloaded!") - case Left(ReloadError(SettingsUpToDate(oldConfig))) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldConfig.hashString().show}) already loaded!") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) settings reloaded!") + case Left(ReloadError(SettingsUpToDate(oldSettings))) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldSettings.hashString().show}) already loaded!") case Left(ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => - logger.error(s"[${requestId.show}] [${config.hashString()}] Cannot reload ROR settings - failure: ${message.show}", ex) + logger.error(s"[${requestId.show}] [${settings.hashString()}] Cannot reload ROR settings - failure: ${message.show}", ex) case Left(ReloadError(ReloadingFailed(StartingFailure(message, None)))) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(ReloadError(RorInstanceStopped)) => @@ -84,12 +84,12 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = { for { _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of in-index settings was forced ...")) - reloadResult <- reloadEngineUsingIndexConfig() + reloadResult <- reloadEngineUsingIndexSettings() _ <- Task.delay(reloadResult match { - case Right(config) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) settings reloaded!") - case Left(IndexSettingsReloadError.ReloadError(SettingsUpToDate(config))) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) already loaded!") + case Right(settings) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) settings reloaded!") + case Left(IndexSettingsReloadError.ReloadError(SettingsUpToDate(settings))) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) already loaded!") case Left(IndexSettingsReloadError.ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}", ex) case Left(IndexSettingsReloadError.ReloadError(ReloadingFailed(StartingFailure(message, None)))) => @@ -102,8 +102,8 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, } yield reloadResult.map(_ => ()) } - def reloadEngineUsingIndexConfig() - (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { + def reloadEngineUsingIndexSettings() + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { reloadInProgress.withPermit { reloadEngineUsingIndexSettingsWithoutPermit() } @@ -120,7 +120,7 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, result.value } - private def saveConfig(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = EitherT { + private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = EitherT { for { saveResult <- settingsManager.saveToIndex(settings) } yield saveResult.left.map(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala similarity index 75% rename from core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala rename to core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala index 9d5cddbcef..84c380e8b6 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/ConfigHash.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala @@ -21,11 +21,11 @@ import tech.beshu.ror.utils.Hasher import scala.language.implicitConversions -private[engines] class ConfigHash(val config: RawRorSettings) extends AnyVal { +private[engines] class SettingsHash(val settings: RawRorSettings) extends AnyVal { - def hashString(): String = Hasher.Sha1.hashString(config.raw) + def hashString(): String = Hasher.Sha1.hashString(settings.raw) } -private[engines] object ConfigHash { - implicit def toConfigHash(config: RawRorSettings): ConfigHash = new ConfigHash(config) +private[engines] object SettingsHash { + implicit def toSettingsHash(config: RawRorSettings): SettingsHash = new SettingsHash(config) } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index e21c8c9c95..46f7e35441 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -27,8 +27,8 @@ import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.{StartingFailure, TestEngine} import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} -import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpirationConfig, EngineState, InitialEngine} -import tech.beshu.ror.boot.engines.ConfigHash.* +import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} +import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration import tech.beshu.ror.configuration.loader.RorTestSettingsManager import tech.beshu.ror.configuration.loader.SettingsManager.SavingIndexSettingsError @@ -52,17 +52,17 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest currentEngineState match { case EngineState.NotStartedYet(None, _) | EngineState.Stopped => TestSettings.NotSet - case EngineState.NotStartedYet(Some(recentConfig), recentExpirationConfig) => - val expiration = recentExpirationConfig.getOrElse(throw new IllegalStateException("Test Config based engine should have an expiration config defined")) - TestSettings.Invalidated(recentConfig, expiration.ttl) - case EngineState.Working(engineWithConfig, _) => - val expiration = engineWithConfig.expirationConfig.getOrElse(throw new IllegalStateException("Test Config based engine should have an expiration config defined")) - TestSettings.Present(engineWithConfig.config, engineWithConfig.engine.core.dependencies, expiration.ttl, expiration.validTo) + case EngineState.NotStartedYet(Some(recentSettings), recentExpiration) => + val expiration = recentExpiration.getOrElse(throw new IllegalStateException("Test settings based engine should have an expiration defined")) + TestSettings.Invalidated(recentSettings, expiration.ttl) + case EngineState.Working(engineWithSettings, _) => + val expiration = engineWithSettings.expiration.getOrElse(throw new IllegalStateException("Test settings based engine should have an expiration defined")) + TestSettings.Present(engineWithSettings.settings, engineWithSettings.engine.core.dependencies, expiration.ttl, expiration.validTo) } } } - def forceReloadTestSettingsEngine(config: RawRorSettings, + def forceReloadTestSettingsEngine(settings: RawRorSettings, ttl: PositiveFiniteDuration) (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, TestSettings.Present]] = { for { @@ -70,33 +70,33 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest reloadResult <- reloadInProgress.withPermit { value { for { - engineExpirationConfig <- reloadEngine(config, ttl).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) - testRorConfig = TestRorSettings.Present( - rawSettings = config, + engineExpiration <- reloadEngine(settings, ttl).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) + testRorSettings = TestRorSettings.Present( + rawSettings = settings, expiration = TestRorSettings.Present.Expiration( - ttl = engineExpirationConfig.expirationConfig.ttl, - validTo = engineExpirationConfig.expirationConfig.validTo + ttl = engineExpiration.expiration.ttl, + validTo = engineExpiration.expiration.validTo ), mocks = boot.authServicesMocksProvider.currentMocks ) - _ <- saveConfigInIndex( - newConfig = testRorConfig, + _ <- saveSettingsInIndex( + newSettings = testRorSettings, onFailure = IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply ) .leftWiden[IndexSettingsReloadWithUpdateError] } yield TestSettings.Present( - dependencies = engineExpirationConfig.engine.core.dependencies, - rawSettings = config, - configuredTtl = engineExpirationConfig.expirationConfig.ttl, - validTo = engineExpirationConfig.expirationConfig.validTo + dependencies = engineExpiration.engine.core.dependencies, + rawSettings = settings, + configuredTtl = engineExpiration.expiration.ttl, + validTo = engineExpiration.expiration.validTo ) } } _ <- Task.delay(reloadResult match { case Right(_) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${config.hashString().show}) reloaded!") - case Left(ReloadError(RawSettingsReloadError.SettingsUpToDate(oldConfig))) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldConfig.hashString().show}) already loaded!") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) reloaded!") + case Left(ReloadError(RawSettingsReloadError.SettingsUpToDate(oldSettings))) => + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldSettings.hashString().show}) already loaded!") case Left(ReloadError(RawSettingsReloadError.ReloadingFailed(StartingFailure(message, Some(ex))))) => logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}", ex) case Left(ReloadError(RawSettingsReloadError.ReloadingFailed(StartingFailure(message, None)))) => @@ -113,19 +113,19 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest (implicit requestId: RequestId): Task[Either[IndexSettingsInvalidationError, Unit]] = { reloadInProgress.withPermit { for { - invalidated <- invalidate(keepPreviousConfiguration = true) + invalidated <- invalidate(keepPreviousSettings = true) result <- invalidated match { case Some(invalidatedEngine) => - val config = TestRorSettings.Present( - rawSettings = invalidatedEngine.config, + val settings = TestRorSettings.Present( + rawSettings = invalidatedEngine.settings, expiration = Expiration( - ttl = invalidatedEngine.expirationConfig.ttl, - validTo = invalidatedEngine.expirationConfig.validTo + ttl = invalidatedEngine.expiration.ttl, + validTo = invalidatedEngine.expiration.validTo ), mocks = boot.authServicesMocksProvider.currentMocks ) - saveConfigInIndex( - newConfig = config, + saveSettingsInIndex( + newSettings = settings, onFailure = IndexSettingsInvalidationError.IndexSettingsSavingError.apply ) .leftWiden[IndexSettingsInvalidationError] @@ -142,18 +142,18 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest reloadInProgress.withPermit { value { for { - config <- readCurrentTestConfigForUpdate() + settings <- readCurrentTestSettingsForUpdate() _ <- updateMocksProvider(mocks) - testRorConfig = TestRorSettings.Present( - rawSettings = config.rawSettings, + testRorSettings = TestRorSettings.Present( + rawSettings = settings.rawSettings, expiration = TestRorSettings.Present.Expiration( - ttl = config.configuredTtl, - validTo = config.validTo + ttl = settings.configuredTtl, + validTo = settings.validTo ), mocks = boot.authServicesMocksProvider.currentMocks ) - _ <- saveConfigInIndex[IndexSettingsUpdateError]( - newConfig = testRorConfig, + _ <- saveSettingsInIndex[IndexSettingsUpdateError]( + newSettings = testRorSettings, onFailure = IndexSettingsUpdateError.IndexSettingsSavingError.apply ) } yield () @@ -161,15 +161,15 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } } - private def readCurrentTestConfigForUpdate() + private def readCurrentTestSettingsForUpdate() (implicit requestId: RequestId): EitherT[Task, IndexSettingsUpdateError, TestSettings.Present] = { EitherT { currentTestSettings() .map { case TestSettings.NotSet => Left(IndexSettingsUpdateError.TestSettingsNotSet) - case config: TestSettings.Present => - Right(config) + case settings: TestSettings.Present => + Right(settings) case _: TestSettings.Invalidated => Left(IndexSettingsUpdateError.TestSettingsInvalidated) } @@ -180,9 +180,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest EitherT.right(Task.delay(boot.authServicesMocksProvider.update(mocks))) } - private def saveConfigInIndex[A](newConfig: TestRorSettings.Present, - onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { - EitherT(testSettingsManager.saveToIndex(newConfig)) + private def saveSettingsInIndex[A](newSettings: TestRorSettings.Present, + onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { + EitherT(testSettingsManager.saveToIndex(newSettings)) .leftMap(onFailure) } @@ -190,34 +190,34 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = { value { for { - loadedConfig <- loadRorConfigFromIndex() - config <- loadedConfig match { + loadedSettings <- loadRorTestSettingsFromIndex() + result <- loadedSettings match { case TestRorSettings.NotSet => - invalidateTestConfigByIndex[IndexSettingsReloadError]() - case TestRorSettings.Present(rawConfig, mocks, expiration) => + invalidateTestSettingsByIndex[IndexSettingsReloadError]() + case TestRorSettings.Present(rawSettings, mocks, expiration) => for { - _ <- reloadEngine(rawConfig, expiration.validTo, expiration.ttl) + _ <- reloadEngine(rawSettings, expiration.validTo, expiration.ttl) .leftMap(IndexSettingsReloadError.ReloadError.apply) .leftWiden[IndexSettingsReloadError] _ <- updateMocksProvider[IndexSettingsReloadError](mocks) } yield () } - } yield config + } yield result } } - private def loadRorConfigFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = EitherT { + private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = EitherT { testSettingsManager .loadFromIndex() .map(_.left.map(IndexSettingsReloadError.LoadingSettingsError.apply)) } - private def invalidateTestConfigByIndex[A]() + private def invalidateTestSettingsByIndex[A]() (implicit requestId: RequestId): EitherT[Task, A, Unit] = { EitherT.right[A] { for { _ <- - invalidate(keepPreviousConfiguration = false) + invalidate(keepPreviousSettings = false) .map { case Some(_) => () case None => () @@ -242,13 +242,13 @@ object TestSettingsBasedReloadableEngine { val engine = initialEngine match { case TestEngine.NotConfigured => InitialEngine.NotConfigured - case TestEngine.Configured(engine, config, expiration) => - InitialEngine.Configured(engine, config, Some(expirationConfig(expiration))) - case TestEngine.Invalidated(config, expiration) => - InitialEngine.Invalidated(config, expirationConfig(expiration)) + case TestEngine.Configured(engine, settings, expiration) => + InitialEngine.Configured(engine, settings, Some(engineExpiration(expiration))) + case TestEngine.Invalidated(settings, expiration) => + InitialEngine.Invalidated(settings, engineExpiration(expiration)) } new TestSettingsBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, testSettingsManager) } - private def expirationConfig(config: TestEngine.Expiration) = EngineExpirationConfig(config.ttl, config.validTo) + private def engineExpiration(expiration: TestEngine.Expiration) = EngineExpiration(expiration.ttl, expiration.validTo) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index 8e27ee1ef9..2e9dedc286 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -25,7 +25,7 @@ import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadEsConfigError.{FileNotFound, MalformedContent, RorSettingsInactiveWhenXpackSecurityIsEnabled} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError.{FileNotFound, MalformedContent, CannotUseRorSslWhenXPackSecurityIsEnabled} import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} @@ -43,7 +43,7 @@ final case class EsConfigBasedRorSettings(boot: RorBootSettings, object EsConfigBasedRorSettings { def from(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[LoadEsConfigError, EsConfigBasedRorSettings]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, EsConfigBasedRorSettings]] = { val configFile = esEnv.elasticsearchYmlFile val result = for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) @@ -81,12 +81,12 @@ object EsConfigBasedRorSettings { private def loadRorSslSettings(esEnv: EsEnv, rorSettingsFromFileParameters: LoadFromFileParameters, xpackSecurity: XpackSecurity) - (implicit systemContext: SystemContext): EitherT[Task, LoadEsConfigError, Option[RorSslSettings]] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { EitherT(RorSslSettings.load(esEnv, rorSettingsFromFileParameters)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) .subflatMap { case Some(ssl) if xpackSecurity.enabled => - Left(RorSettingsInactiveWhenXpackSecurityIsEnabled) + Left(CannotUseRorSslWhenXPackSecurityIsEnabled) case rorSsl@(Some(_) | None) => Right(rorSsl) } @@ -140,11 +140,11 @@ object EsConfigBasedRorSettings { private final case class XpackSecurity(enabled: Boolean) - sealed trait LoadEsConfigError - object LoadEsConfigError { - final case class FileNotFound(file: File) extends LoadEsConfigError - final case class MalformedContent(file: File, message: String) extends LoadEsConfigError - case object RorSettingsInactiveWhenXpackSecurityIsEnabled extends LoadEsConfigError + sealed trait LoadingError + object LoadingError { + final case class FileNotFound(file: File) extends LoadingError + final case class MalformedContent(file: File, message: String) extends LoadingError + case object CannotUseRorSslWhenXPackSecurityIsEnabled extends LoadingError } private object decoders { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala similarity index 100% rename from core/src/main/scala/tech/beshu/ror/configuration/SslConfiguration.scala rename to core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index 4bfa8b6aad..d3698a55ec 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, Cann final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, - rarRorConfigYamlParser: RawRorSettingsYamlParser) + rawRorSettingsYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[RawRorSettings] with Logging { @@ -43,7 +43,7 @@ final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val se source .find(_._1 == Const.settingsKey) .map { case (_, rorYamlString) => - rarRorConfigYamlParser + rawRorSettingsYamlParser .fromString(rorYamlString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index 89dcc02c56..45b4302936 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -53,7 +53,7 @@ import scala.util.Try final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, indexJsonContentService: IndexJsonContentService, - rarRorConfigYamlParser: RawRorSettingsYamlParser) + rawRorSettingsYamlParser: RawRorSettingsYamlParser) extends IndexSettingsManager[TestRorSettings] with Logging { @@ -91,7 +91,7 @@ final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val se rawRorConfigString <- getConfigProperty(config, Const.properties.settings) authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) rawRorConfig <- EitherT { - rarRorConfigYamlParser + rawRorSettingsYamlParser .fromString(rawRorConfigString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala index f8d40b9688..ad553c0be1 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala @@ -26,22 +26,22 @@ import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotEx import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} class FileRorSettingsLoader(rorSettingsFile: File, - rarRorConfigYamlParser: RawRorSettingsYamlParser) + rawRorSettingsYamlParser: RawRorSettingsYamlParser) extends RorSettingsLoader[FileRorSettingsLoader.Error] { override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { val file = rorSettingsFile (for { _ <- checkIfFileExist(file) - config <- loadConfigFromFile(file) - } yield config).value + settings <- loadSettingsFromFile(file) + } yield settings).value } private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], File] = EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) - private def loadConfigFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { - EitherT(rarRorConfigYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) + private def loadSettingsFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { + EitherT(rawRorSettingsYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) } } diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index e57dd23a53..af35b162f2 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -59,7 +59,7 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError.{KibanaRuleTogetherWith, KibanaUserDataRuleTogetherWith} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadEsConfigError +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* @@ -398,10 +398,10 @@ trait LogsShowInstances case AccessRequirement.MustBeAbsent(value) => s"~${value.show}" } - implicit val loadEsConfigErrorShow: Show[LoadEsConfigError] = Show.show { - case LoadEsConfigError.FileNotFound(file) => s"Cannot find elasticsearch settings file: [${file.show}]" - case LoadEsConfigError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" - case LoadEsConfigError.RorSettingsInactiveWhenXpackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" + implicit val loadEsConfigErrorShow: Show[LoadingError] = Show.show { + case LoadingError.FileNotFound(file) => s"Cannot find elasticsearch settings file: [${file.show}]" + case LoadingError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" + case LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" } } From 3a74a10820d256003d00e1c99f166bb05827236a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 11 Jul 2025 19:50:22 +0200 Subject: [PATCH 017/103] refactoring --- .../main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala | 4 ++-- core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala | 6 +++--- core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala | 4 ++-- .../boot/engines/MainSettingsBasedReloadableEngine.scala | 4 ++-- .../boot/engines/TestSettingsBasedReloadableEngine.scala | 4 ++-- .../{loader => manager}/RorMainSettingsManager.scala | 7 ++++--- .../{loader => manager}/RorTestSettingsManager.scala | 5 +++-- .../{loader => manager}/SettingsManager.scala | 4 ++-- 8 files changed, 20 insertions(+), 18 deletions(-) rename core/src/main/scala/tech/beshu/ror/configuration/{loader => manager}/RorMainSettingsManager.scala (95%) rename core/src/main/scala/tech/beshu/ror/configuration/{loader => manager}/RorTestSettingsManager.scala (96%) rename core/src/main/scala/tech/beshu/ror/configuration/{loader => manager}/SettingsManager.scala (91%) diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index 8a3d5fedf0..431d76177c 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -29,8 +29,8 @@ import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.loader.RorMainSettingsManager -import tech.beshu.ror.configuration.loader.SettingsManager.LoadingFromIndexError +import tech.beshu.ror.configuration.manager.RorMainSettingsManager +import tech.beshu.ror.configuration.manager.SettingsManager.LoadingFromIndexError import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 5c894a36ba..fc4beb1bf9 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -35,9 +35,9 @@ import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.index.* -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.RorMainSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError} +import tech.beshu.ror.configuration.manager.* +import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError} import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 417f8d538b..56f63e3a1b 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -32,8 +32,8 @@ import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainRorSettingsApi, TestRorSettingsApi} import tech.beshu.ror.boot.engines.{Engines, MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.loader.{RorMainSettingsManager, RorTestSettingsManager} +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.{RorMainSettingsManager, RorTestSettingsManager} import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 13f466633d..c94e30013b 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -29,8 +29,8 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.loader.RorMainSettingsManager -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.RorMainSettingsManager +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 46f7e35441..6937b2937f 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -30,8 +30,8 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration -import tech.beshu.ror.configuration.loader.RorTestSettingsManager -import tech.beshu.ror.configuration.loader.SettingsManager.SavingIndexSettingsError +import tech.beshu.ror.configuration.manager.RorTestSettingsManager +import tech.beshu.ror.configuration.manager.SettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala similarity index 95% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index e312c3f846..e67d2ad94c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.loader +package tech.beshu.ror.configuration.manager import cats.Show import cats.data.EitherT @@ -25,9 +25,10 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParame import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.RorMainSettingsManager.LoadingFromFileError import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} +import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala similarity index 96% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala index 2c31940c4e..3ca04a6e83 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.loader +package tech.beshu.ror.configuration.manager import cats.data.EitherT import monix.eval.Task @@ -24,8 +24,9 @@ import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, Loading import tech.beshu.ror.configuration.TestRorSettings import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +import tech.beshu.ror.configuration.loader.RorSettingsLoader import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.implicits.* import scala.language.postfixOps diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala similarity index 91% rename from core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala index 8403c96cb0..cb3ef0f097 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/SettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala @@ -14,12 +14,12 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.loader +package tech.beshu.ror.configuration.manager import cats.Show import monix.eval.Task import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters -import tech.beshu.ror.configuration.loader.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} trait SettingsManager[SETTINGS] { From 16615b99384cca23e95516298ec81b189e9235c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 14 Jul 2025 22:16:00 +0200 Subject: [PATCH 018/103] refactoring --- .../tech/beshu/ror/api/AuthMockApi.scala | 1 + .../beshu/ror/api/MainRorSettingsApi.scala | 14 ++++++-- .../beshu/ror/api/TestRorSettingsApi.scala | 1 + .../tech/beshu/ror/boot/ReadonlyRest.scala | 6 ++-- .../tech/beshu/ror/boot/RorInstance.scala | 1 + .../MainSettingsBasedReloadableEngine.scala | 13 +++---- .../TestSettingsBasedReloadableEngine.scala | 7 ++-- ...ServiceBasedIndexMainSettingsManager.scala | 4 ++- .../index/IndexSettingsManager.scala | 11 ------ .../manager/RorMainSettingsManager.scala | 36 +++++++++++-------- .../manager/RorTestSettingsManager.scala | 27 ++++++++------ .../manager/SettingsManager.scala | 5 --- .../main/scala/tech/beshu/ror/implicits.scala | 20 +++++++++-- 13 files changed, 82 insertions(+), 64 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index d6144ebe0b..5a95554583 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -33,6 +33,7 @@ import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RequestId, User} import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.boot.RorInstance.{IndexSettingsUpdateError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} +import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.CirceErrorOps diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index 431d76177c..ed5d953e90 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -29,12 +29,15 @@ import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.manager.RorMainSettingsManager import tech.beshu.ror.configuration.manager.SettingsManager.LoadingFromIndexError -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps -class MainRorSettingsApi(rorInstance: RorInstance, +class MainRorSettingsApi(esConfigBasedRorSettings: EsConfigBasedRorSettings, + rorInstance: RorInstance, settingsYamlParser: RawRorSettingsYamlParser, settingsManager: RorMainSettingsManager) extends Logging { @@ -85,7 +88,12 @@ class MainRorSettingsApi(rorInstance: RorInstance, private def provideRorFileSettings(): Task[MainSettingsResponse] = { settingsManager - .loadFromFile(???) + .loadFromFile { + esConfigBasedRorSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => parameters + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, fallbackParameters) => fallbackParameters + } + } .map { case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) case Left(error) => ProvideFileMainSettings.Failure(error.show) diff --git a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala index 9a3b0969e9..7a38cccb7a 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala @@ -29,6 +29,7 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, RawSettingsReloadError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index fc4beb1bf9..5e2475340a 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -51,7 +51,7 @@ class ReadonlyRest(coreFactory: CoreFactory, (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { - private [boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) + private[boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { @@ -69,7 +69,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadMainRorSettings(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { + rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => EitherT(rorSettingsLoader.loadFromFile(settings)) @@ -81,7 +81,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadRorTestSettings(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorTestSettingsManager): EitherT[Task, StartingFailure, TestRorSettings] = { + rorSettingsLoader: RorTestSettingsManager): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 56f63e3a1b..500d5486b4 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -84,6 +84,7 @@ class RorInstance private(boot: ReadonlyRest, private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) private val mainSettingsRestApi = new MainRorSettingsApi( + esConfigBasedRorSettings = esConfig, rorInstance = this, rarRorSettingsYamlParser, mainSettingsManager diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index c94e30013b..d39e53d931 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -120,19 +120,14 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, result.value } - private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = EitherT { - for { - saveResult <- settingsManager.saveToIndex(settings) - } yield saveResult.left.map(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) + private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { + EitherT(settingsManager.saveToIndex(settings)) + .leftMap(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) } private def loadRorSettingFromIndex() = { EitherT(settingsManager.loadFromIndex()) - .leftMap { - case LoadingFromIndexError.IndexParsingError(message) => ??? - case LoadingFromIndexError.IndexUnknownStructure => ??? - case LoadingFromIndexError.IndexNotExist => ??? - } + .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 6937b2937f..0587ae2d47 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -206,10 +206,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } } - private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = EitherT { - testSettingsManager - .loadFromIndex() - .map(_.left.map(IndexSettingsReloadError.LoadingSettingsError.apply)) + private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { + EitherT(testSettingsManager.loadFromIndex()) + .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) } private def invalidateTestSettingsByIndex[A]() diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index d3698a55ec..4d1231cf68 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -47,7 +47,9 @@ final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val se .fromString(rorYamlString) .map(_.left.map(ParsingError.apply)) } - .getOrElse(settingsLoaderError(UnknownStructureOfIndexDocument)) + .getOrElse { + settingsLoaderError(UnknownStructureOfIndexDocument) + } case Left(CannotReachContentSource) => settingsLoaderError(IndexNotExist) case Left(ContentNotFound) => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala index 273408fee6..d49326c63b 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.configuration.index -import cats.Show import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} @@ -43,20 +42,10 @@ object IndexSettingsManager { object LoadingIndexSettingsError { case object IndexNotExist extends LoadingIndexSettingsError case object UnknownStructureOfIndexDocument extends LoadingIndexSettingsError - - // todo: move to implicits? - implicit val show: Show[LoadingIndexSettingsError] = Show.show { - case IndexNotExist => "Cannot find settings index" - case UnknownStructureOfIndexDocument => s"Unknown structure of index settings" - } } sealed trait SavingIndexSettingsError object SavingIndexSettingsError { case object CannotSaveSettings extends SavingIndexSettingsError - - implicit val show: Show[SavingIndexSettingsError] = Show.show { - case CannotSaveSettings => "Cannot save settings in index" - } } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index e67d2ad94c..d699406436 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -16,27 +16,25 @@ */ package tech.beshu.ror.configuration.manager -import cats.Show +import better.files.File import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParameters, LoadFromIndexParameters} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParameters, LoadFromIndexParameters, LoadingRorCoreStrategy} import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} import tech.beshu.ror.configuration.index.IndexSettingsManager -import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* -import java.nio.file.Path import scala.language.postfixOps // todo: refactor methods -class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSettings]) +class RorMainSettingsManager private(indexSettingsManager: IndexSettingsManager[RawRorSettings]) extends SettingsManager[RawRorSettings] with Logging { def loadFromFile(loadFromFileParameters: LoadFromFileParameters): Task[Either[LoadingFromFileError, RawRorSettings]] = { @@ -64,7 +62,11 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - ??? + EitherT(indexSettingsManager.save(settings)) + .leftMap { + case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => SettingsManager.SavingIndexSettingsError.CannotSaveSettings + } + .value } private def attemptLoadingFromIndex(parameters: LoadFromIndexParameters, @@ -143,11 +145,11 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } } - private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]) = + private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]) = error match { case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure + case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist + case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure } private def logIndexLoadingError[A](error: LoadingFromIndexError): Unit = { @@ -161,14 +163,20 @@ class RorMainSettingsManager(indexSettingsManager: IndexSettingsManager[RawRorSe } } } + object RorMainSettingsManager { + def create(esConfigBasedRorSettings: EsConfigBasedRorSettings): RorMainSettingsManager = { + esConfigBasedRorSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => ??? + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => ??? + } + } + sealed trait LoadingFromFileError extends LoadingError object LoadingFromFileError { final case class FileParsingError(message: String) extends LoadingFromFileError - final case class FileNotExist(path: Path) extends LoadingFromFileError - - implicit val show: Show[LoadingFromFileError] = ??? + final case class FileNotExist(file: File) extends LoadingFromFileError } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala index 3ca04a6e83..5213b6bd12 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala @@ -21,17 +21,19 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} -import tech.beshu.ror.configuration.TestRorSettings +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, TestRorSettings} import tech.beshu.ror.configuration.index.IndexSettingsManager import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.RorSettingsLoader +import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.implicits.* import scala.language.postfixOps -class RorTestSettingsManager(indexConfigManager: IndexSettingsManager[TestRorSettings]) +class RorTestSettingsManager(esConfigBasedRorSettings: EsConfigBasedRorSettings, + fileSettingsLoader: FileRorSettingsLoader, + indexSettingsManager: IndexSettingsManager[TestRorSettings]) extends SettingsManager[TestRorSettings] with Logging { def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, @@ -54,11 +56,15 @@ class RorTestSettingsManager(indexConfigManager: IndexSettingsManager[TestRorSet } override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { - ??? + loadTestRorConfigFromIndex(LoadingDelay.none) } override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - ??? + EitherT(indexSettingsManager.save(settings)) + .leftMap { + case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => SettingsManager.SavingIndexSettingsError.CannotSaveSettings + } + .value } private def attemptLoadingConfigFromIndex(parameters: LoadFromIndexParameters, @@ -67,7 +73,7 @@ class RorTestSettingsManager(indexConfigManager: IndexSettingsManager[TestRorSet case 0 => fallback case attemptsCount => - loadTestRorConfigFromIndex(parameters.copy(loadingDelay = LoadingDelay.none)).flatMap { + loadTestRorConfigFromIndex(LoadingDelay.none).flatMap { case Left(LoadingFromIndexError.IndexNotExist) => attemptLoadingConfigFromIndex( parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), @@ -83,13 +89,12 @@ class RorTestSettingsManager(indexConfigManager: IndexSettingsManager[TestRorSet } } - private def loadTestRorConfigFromIndex(settings: LoadFromIndexParameters) = { - val rorConfigIndex = settings.rorSettingsIndex - val loadingDelay = settings.loadingDelay + private def loadTestRorConfigFromIndex(loadingDelay: LoadingDelay) = { + val settingsIndex = indexSettingsManager.settingsIndex // todo: log is ok? - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${rorConfigIndex.index.show}) ...") + logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...") EitherT { - indexConfigManager + indexSettingsManager .load() .delayExecution(loadingDelay.value.value) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala index cb3ef0f097..aa0e995a50 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.configuration.manager -import cats.Show import monix.eval.Task import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} @@ -38,14 +37,10 @@ object SettingsManager { final case class IndexParsingError(message: String) extends LoadingFromIndexError case object IndexUnknownStructure extends LoadingFromIndexError case object IndexNotExist extends LoadingFromIndexError - - implicit val show: Show[LoadingFromIndexError] = ??? } sealed trait SavingIndexSettingsError object SavingIndexSettingsError { case object CannotSaveSettings extends SavingIndexSettingsError - - implicit val show: Show[SavingIndexSettingsError] = ??? } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index af35b162f2..ca5f30af60 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -33,7 +33,6 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UserGroupsSearchFilterConfig.UserGroupsSearchMode.* import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.{Dn, LdapService} import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.rules.Rule.{RuleName, RuleResult} import tech.beshu.ror.accesscontrol.blocks.rules.elasticsearch.{ActionsRule, FieldsRule, FilterRule, ResponseFieldsRule} import tech.beshu.ror.accesscontrol.blocks.rules.kibana.* @@ -44,8 +43,7 @@ import tech.beshu.ror.accesscontrol.blocks.variables.runtime.{RuntimeResolvableV import tech.beshu.ror.accesscontrol.blocks.variables.startup.StartupResolvableVariableCreator import tech.beshu.ror.accesscontrol.blocks.variables.transformation.domain.* import tech.beshu.ror.accesscontrol.domain.* -import tech.beshu.ror.accesscontrol.domain.AccessRequirement.{MustBeAbsent, MustBePresent} -import tech.beshu.ror.accesscontrol.domain.Address.Ip +import tech.beshu.ror.accesscontrol.domain.AccessRequirement.MustBePresent import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Remote.ClusterName import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.Strategy import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId @@ -60,6 +58,8 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError. import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError +import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* @@ -404,4 +404,18 @@ trait LogsShowInstances case LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" } + implicit val loadingFromIndexErrorShow: Show[LoadingFromIndexError] = Show.show { + case LoadingFromIndexError.IndexNotExist => "Cannot find ReadonlyREST settings index" + case LoadingFromIndexError.IndexUnknownStructure => "Unknown structure of ReadonlyREST index settings document" + case LoadingFromIndexError.IndexParsingError(message) => s"Cannot parse in-index ReadonlyREST settings. Cause: $message" + } + + implicit val loadingFromFileErrorShow: Show[LoadingFromFileError] = Show.show { + case LoadingFromFileError.FileParsingError(message) => s"Cannot parse file ReadonlyREST settings. Cause: $message" + case LoadingFromFileError.FileNotExist(file) => s"Cannot find ReadonlyREST settings file: ${file.pathAsString}" + } + + implicit val savingIndexSettingsErrorShow: Show[SavingIndexSettingsError] = Show.show { + case SavingIndexSettingsError.CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" + } } From 34cd968ef0fbdd8d33e5882399f5ae4b2aea40c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 15 Jul 2025 16:22:30 +0200 Subject: [PATCH 019/103] refactoring --- .../beshu/ror/api/MainRorSettingsApi.scala | 15 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 60 +++---- .../tech/beshu/ror/boot/RorInstance.scala | 117 +++++------- .../MainSettingsBasedReloadableEngine.scala | 2 +- .../TestSettingsBasedReloadableEngine.scala | 2 +- ...ServiceBasedIndexMainSettingsManager.scala | 6 +- ...ServiceBasedIndexTestSettingsManager.scala | 6 +- .../index/IndexSettingsManager.scala | 3 + .../loader/FileRorSettingsLoader.scala | 4 +- .../manager/FileSettingsManager.scala | 34 ++++ ...ger.scala => InIndexSettingsManager.scala} | 13 +- .../manager/RorMainSettingsManager.scala | 169 ++++++++++-------- .../manager/RorTestSettingsManager.scala | 113 ++++++------ .../main/scala/tech/beshu/ror/implicits.scala | 4 +- 14 files changed, 283 insertions(+), 265 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala rename core/src/main/scala/tech/beshu/ror/configuration/manager/{SettingsManager.scala => InIndexSettingsManager.scala} (71%) diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index ed5d953e90..dbda9f1b1e 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -29,15 +29,13 @@ import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.manager.RorMainSettingsManager -import tech.beshu.ror.configuration.manager.SettingsManager.LoadingFromIndexError -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps -class MainRorSettingsApi(esConfigBasedRorSettings: EsConfigBasedRorSettings, - rorInstance: RorInstance, +class MainRorSettingsApi(rorInstance: RorInstance, settingsYamlParser: RawRorSettingsYamlParser, settingsManager: RorMainSettingsManager) extends Logging { @@ -88,12 +86,7 @@ class MainRorSettingsApi(esConfigBasedRorSettings: EsConfigBasedRorSettings, private def provideRorFileSettings(): Task[MainSettingsResponse] = { settingsManager - .loadFromFile { - esConfigBasedRorSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => parameters - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, fallbackParameters) => fallbackParameters - } - } + .loadFromFile() .map { case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) case Left(error) => ProvideFileMainSettings.Failure(error.show) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 5e2475340a..ec3d9e7830 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,10 +34,10 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.index.* import tech.beshu.ror.configuration.manager.* -import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError} +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError +import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -49,35 +49,24 @@ class ReadonlyRest(coreFactory: CoreFactory, auditSinkServiceCreator: AuditSinkServiceCreator, val esEnv: EsEnv) (implicit systemContext: SystemContext, - scheduler: Scheduler) extends Logging { + scheduler: Scheduler) + extends Logging { private[boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - rorYamlParser <- lift(new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize)) - rorMainSettingsLoader <- lift(new RorMainSettingsManager( - new IndexJsonContentServiceBasedIndexMainSettingsManager(esConfig.rorSettingsIndex, indexContentService, rorYamlParser) - )) - rorTestSettingsLoader <- lift(new RorTestSettingsManager( - new IndexJsonContentServiceBasedIndexTestSettingsManager(esConfig.rorSettingsIndex, indexContentService, rorYamlParser) - )) - loadedMainRorSettings <- loadMainRorSettings(esConfig, rorMainSettingsLoader) - loadedTestRorSettings <- loadRorTestSettings(esConfig, rorTestSettingsLoader) - instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsLoader, loadedTestRorSettings, rorTestSettingsLoader) + rorMainSettingsManager <- lift(RorMainSettingsManager.create(esConfig, indexContentService)) + rorTestSettingsManager <- lift(RorTestSettingsManager.create(esConfig, indexContentService)) + loadedMainRorSettings <- loadMainSettingsAccordingToStrategy(rorMainSettingsManager) + loadedTestRorSettings <- loadRorTestSettings(esConfig, rorTestSettingsManager) + instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsManager, loadedTestRorSettings, rorTestSettingsManager) } yield instance).value } - private def loadMainRorSettings(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { - esConfig.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - EitherT(rorSettingsLoader.loadFromFile(settings)) - .leftMap(toStartingFailure) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, fallbackSettings) => - EitherT(rorSettingsLoader.loadFromIndexWithFileFallback(settings, fallbackSettings)) - .leftMap(toStartingFailure) - } + private def loadMainSettingsAccordingToStrategy(rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { + EitherT(rorSettingsLoader.loadAccordingToStrategy()) + .leftMap(toStartingFailure) } private def loadRorTestSettings(esConfig: EsConfigBasedRorSettings, @@ -87,10 +76,7 @@ class ReadonlyRest(coreFactory: CoreFactory, EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => EitherT { - rorSettingsLoader.loadFromIndexWithFallback( - loadFromIndexParameters = parameters, - fallbackSettings = notSetTestRorSettings - ) + rorSettingsLoader.loadFromIndex() }.leftFlatMap { case LoadingFromIndexError.IndexParsingError(message) => logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") @@ -107,15 +93,15 @@ class ReadonlyRest(coreFactory: CoreFactory, private def toStartingFailure(error: LoadingError) = { error match { - case LoadingFromFileError.FileParsingError(message) => + case Left(LoadingFromFileError.FileParsingError(message)) => StartingFailure(message) - case LoadingFromFileError.FileNotExist(path) => + case Left(LoadingFromFileError.FileNotExist(path)) => StartingFailure(s"Cannot find settings file: ${path.show}") - case LoadingFromIndexError.IndexParsingError(message) => + case Right(LoadingFromIndexError.IndexParsingError(message)) => StartingFailure(message) - case LoadingFromIndexError.IndexUnknownStructure => + case Right(LoadingFromIndexError.IndexUnknownStructure) => StartingFailure(s"Settings index is malformed") - case LoadingFromIndexError.IndexNotExist => + case Right(LoadingFromIndexError.IndexNotExist) => StartingFailure(s"Settings index doesn't exist") } } @@ -181,13 +167,7 @@ class ReadonlyRest(coreFactory: CoreFactory, testSettingsManager: RorTestSettingsManager, alreadyLoadedSettings: RawRorSettings) = { EitherT.right[StartingFailure] { - val rorSettingsMaxSize = esConfig.loadingRorCoreStrategy.rorSettingsMaxSize - esConfig.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - RorInstance.createWithoutPeriodicIndexCheck(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - RorInstance.createWithPeriodicIndexCheck(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager, settings.refreshInterval, rorSettingsMaxSize) - } + RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager) } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 500d5486b4..badb7042d5 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -24,15 +24,15 @@ import monix.catnap.Semaphore import monix.eval.Task import monix.execution.{Cancelable, Scheduler} import org.apache.logging.log4j.scala.Logging -import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainRorSettingsApi, TestRorSettingsApi} import tech.beshu.ror.boot.engines.{Engines, MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.configuration.manager.{RorMainSettingsManager, RorTestSettingsManager} import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* @@ -48,8 +48,7 @@ class RorInstance private(boot: ReadonlyRest, mainSettingsManager: RorMainSettingsManager, testInitialEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], - testSettingsManager: RorTestSettingsManager, - rorSettingsMaxSize: Information) + testSettingsManager: RorTestSettingsManager) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -81,18 +80,11 @@ class RorInstance private(boot: ReadonlyRest, testSettingsManager ) - private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(rorSettingsMaxSize) - - private val mainSettingsRestApi = new MainRorSettingsApi( - esConfigBasedRorSettings = esConfig, - rorInstance = this, - rarRorSettingsYamlParser, - mainSettingsManager - ) - - private val authMockRestApi = new AuthMockApi(rorInstance = this) + private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize) + private val mainSettingsRestApi = new MainRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser, mainSettingsManager) private val testSettingsRestApi = new TestRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser) + private val authMockRestApi = new AuthMockApi(rorInstance = this) def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) @@ -155,7 +147,7 @@ class RorInstance private(boot: ReadonlyRest, } private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, - reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Cancelable = { + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Cancelable = { logger.debug(s"[CLUSTERWIDE SETTINGS] Scheduling next in-index settings check within ${interval.show}") scheduler.scheduleOnce(interval.value) { implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) @@ -173,7 +165,7 @@ class RorInstance private(boot: ReadonlyRest, } private def logSettingsReloadResult(settingsReloadResult: (SettingsType, Either[ScheduledReloadError, Unit])) - (implicit requestId: RequestId): Unit = settingsReloadResult match { + (implicit requestId: RequestId): Unit = settingsReloadResult match { case (_, Right(())) => case (name, Left(ReloadingInProgress)) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Reloading of ${name.show} engine in progress ... skipping") @@ -220,6 +212,47 @@ class RorInstance private(boot: ReadonlyRest, object RorInstance { + def create(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, + mainEngine: ReadonlyRest.MainEngine, + testEngine: ReadonlyRest.TestEngine, + mainSettingsManager: RorMainSettingsManager, + testSettingsManager: RorTestSettingsManager) + (implicit systemContext: SystemContext, + scheduler: Scheduler): Task[RorInstance] = { + esConfig.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => + createInstance(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsManager, testSettingsManager) + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => + createInstance(boot, esConfig, Mode.WithPeriodicIndexCheck(settings.refreshInterval), mainEngine, testEngine, mainSettingsManager, testSettingsManager) + } + } + + private def createInstance(boot: ReadonlyRest, + esConfig: EsConfigBasedRorSettings, + mode: RorInstance.Mode, + mainEngine: ReadonlyRest.MainEngine, + testEngine: ReadonlyRest.TestEngine, + mainSettingsManager: RorMainSettingsManager, + testSettingsManager: RorTestSettingsManager) + (implicit systemContext: SystemContext, + scheduler: Scheduler) = { + for { + isReloadInProgressSemaphore <- Semaphore[Task](1) + isTestReloadInProgressSemaphore <- Semaphore[Task](1) + } yield new RorInstance( + boot = boot, + esConfig = esConfig, + mode = mode, + mainInitialEngine = mainEngine, + mainReloadInProgress = isReloadInProgressSemaphore, + mainSettingsManager = mainSettingsManager, + testInitialEngine = testEngine, + testReloadInProgress = isTestReloadInProgressSemaphore, + testSettingsManager = testSettingsManager + ) + } + sealed trait RawSettingsReloadError object RawSettingsReloadError { final case class ReloadingFailed(failure: ReadonlyRest.StartingFailure) extends RawSettingsReloadError @@ -268,58 +301,6 @@ object RorInstance { configuredTtl: PositiveFiniteDuration) extends TestSettings } - def createWithPeriodicIndexCheck(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: RorMainSettingsManager, - testSettingsManager: RorTestSettingsManager, - refreshInterval: RefreshInterval, - rorSettingsMaxSize: Information) - (implicit systemContext: SystemContext, - scheduler: Scheduler): Task[RorInstance] = { - create(boot, esConfig, Mode.WithPeriodicIndexCheck(refreshInterval), mainEngine, testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) - } - - def createWithoutPeriodicIndexCheck(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: RorMainSettingsManager, - testSettingsManager: RorTestSettingsManager, - rorSettingsMaxSize: Information) - (implicit systemContext: SystemContext, - scheduler: Scheduler): Task[RorInstance] = { - create(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsManager, testSettingsManager, rorSettingsMaxSize) - } - - private def create(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - mode: RorInstance.Mode, - mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: RorMainSettingsManager, - testSettingsManager: RorTestSettingsManager, - rorSettingsMaxSize: Information) - (implicit systemContext: SystemContext, - scheduler: Scheduler) = { - for { - isReloadInProgressSemaphore <- Semaphore[Task](1) - isTestReloadInProgressSemaphore <- Semaphore[Task](1) - } yield new RorInstance( - boot = boot, - esConfig = esConfig, - mode = mode, - mainInitialEngine = mainEngine, - mainReloadInProgress = isReloadInProgressSemaphore, - mainSettingsManager = mainSettingsManager, - testInitialEngine = testEngine, - testReloadInProgress = isTestReloadInProgressSemaphore, - testSettingsManager = testSettingsManager, - rorSettingsMaxSize = rorSettingsMaxSize - ) - } - private sealed trait Mode private object Mode { final case class WithPeriodicIndexCheck(reloadInterval: RefreshInterval) extends Mode diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index d39e53d931..0bccea08f6 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -30,7 +30,7 @@ import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.manager.RorMainSettingsManager -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 0587ae2d47..dd0354c994 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, Engin import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration import tech.beshu.ror.configuration.manager.RorTestSettingsManager -import tech.beshu.ror.configuration.manager.SettingsManager.SavingIndexSettingsError +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index 4d1231cf68..87db7a3770 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -30,8 +30,8 @@ import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, - indexJsonContentService: IndexJsonContentService, - rawRorSettingsYamlParser: RawRorSettingsYamlParser) + override val rorSettingsYamlParser: RawRorSettingsYamlParser, + indexJsonContentService: IndexJsonContentService) extends IndexSettingsManager[RawRorSettings] with Logging { @@ -43,7 +43,7 @@ final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val se source .find(_._1 == Const.settingsKey) .map { case (_, rorYamlString) => - rawRorSettingsYamlParser + rorSettingsYamlParser .fromString(rorYamlString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index 45b4302936..c013bab9c3 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -52,8 +52,8 @@ import scala.concurrent.duration.Duration import scala.util.Try final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, - indexJsonContentService: IndexJsonContentService, - rawRorSettingsYamlParser: RawRorSettingsYamlParser) + override val rorSettingsYamlParser: RawRorSettingsYamlParser, + indexJsonContentService: IndexJsonContentService) extends IndexSettingsManager[TestRorSettings] with Logging { @@ -91,7 +91,7 @@ final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val se rawRorConfigString <- getConfigProperty(config, Const.properties.settings) authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) rawRorConfig <- EitherT { - rawRorSettingsYamlParser + rorSettingsYamlParser .fromString(rawRorConfigString) .map(_.left.map(ParsingError.apply)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala index d49326c63b..469fa9edf2 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -18,6 +18,7 @@ package tech.beshu.ror.configuration.index import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +import tech.beshu.ror.configuration.RawRorSettingsYamlParser import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} import tech.beshu.ror.configuration.loader.RorSettingsLoader import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError @@ -28,6 +29,8 @@ trait IndexSettingsManager[SETTINGS] { def settingsIndex: RorSettingsIndex + def rorSettingsYamlParser: RawRorSettingsYamlParser + def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala index ad553c0be1..ae0cf727ce 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala @@ -20,15 +20,17 @@ import better.files.File import cats.Show import cats.data.EitherT import monix.eval.Task +import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} class FileRorSettingsLoader(rorSettingsFile: File, rawRorSettingsYamlParser: RawRorSettingsYamlParser) extends RorSettingsLoader[FileRorSettingsLoader.Error] { + def settingsFile: File = rorSettingsFile + override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { val file = rorSettingsFile (for { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala new file mode 100644 index 0000000000..3a0672b27a --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala @@ -0,0 +1,34 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.configuration.manager + +import better.files.File +import monix.eval.Task +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError + +trait FileSettingsManager[SETTINGS] { + + def loadFromFile(): Task[Either[LoadingFromFileError, SETTINGS]] +} +object FileSettingsManager { + + sealed trait LoadingFromFileError + object LoadingFromFileError { + final case class FileParsingError(message: String) extends LoadingFromFileError + final case class FileNotExist(file: File) extends LoadingFromFileError + } +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala similarity index 71% rename from core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala rename to core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala index aa0e995a50..2288f64b90 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/SettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala @@ -17,22 +17,17 @@ package tech.beshu.ror.configuration.manager import monix.eval.Task -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -trait SettingsManager[SETTINGS] { - - def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - fallback: Task[Either[LoadingError, SETTINGS]]): Task[Either[LoadingError, SETTINGS]] +trait InIndexSettingsManager[SETTINGS] { def loadFromIndex(): Task[Either[LoadingFromIndexError, SETTINGS]] def saveToIndex(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] } -object SettingsManager { - trait LoadingError +object InIndexSettingsManager { - sealed trait LoadingFromIndexError extends LoadingError + sealed trait LoadingFromIndexError object LoadingFromIndexError { final case class IndexParsingError(message: String) extends LoadingFromIndexError case object IndexUnknownStructure extends LoadingFromIndexError diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index d699406436..13cb0bdada 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -16,89 +16,100 @@ */ package tech.beshu.ror.configuration.manager -import better.files.File import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.{LoadFromFileParameters, LoadFromIndexParameters, LoadingRorCoreStrategy} -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} -import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} +import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexMainSettingsManager, IndexSettingsManager} import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} -import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.implicits.* +import scala.concurrent.duration.FiniteDuration import scala.language.postfixOps // todo: refactor methods -class RorMainSettingsManager private(indexSettingsManager: IndexSettingsManager[RawRorSettings]) - extends SettingsManager[RawRorSettings] with Logging { +class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, + fileSettingsLoader: FileRorSettingsLoader, + indexSettingsManager: IndexSettingsManager[RawRorSettings]) + extends FileSettingsManager[RawRorSettings] + with InIndexSettingsManager[RawRorSettings] + with Logging { - def loadFromFile(loadFromFileParameters: LoadFromFileParameters): Task[Either[LoadingFromFileError, RawRorSettings]] = { - forceLoadFromFile(loadFromFileParameters) - } + def loadAccordingToStrategy(): Task[Either[LoadingError, RawRorSettings]] = { + def loadFromFileWithLoadingError(): Task[Either[LoadingError, RawRorSettings]] = + loadFromFile().map(_.left.map(Left.apply)) - override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { - loadRorSettingsFromIndex(loadingDelay = LoadingDelay.none) + esConfigBasedRorSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => + loadFromFileWithLoadingError() + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => + for { + _ <- wait(parameters.loadingDelay.value.value) + result <- attemptLoadingFromIndex( + loadingAttemptsInterval = parameters.loadingAttemptsInterval, + loadingAttemptsCount = parameters.loadingAttemptsCount, + fallback = loadFromFileWithLoadingError() + ) + } yield result + } } - override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { - attemptLoadingFromIndex( - parameters = loadFromIndexParameters, - fallback = fallback - ) + override def loadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { + forceLoadFromFile() } - def loadFromIndexWithFileFallback(loadFromIndexParameters: LoadFromIndexParameters, - loadFromFileParameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { - loadFromIndexWithFallback( - loadFromIndexParameters, - loadRorSettingsFromFile(loadFromFileParameters) - ) + override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { + loadRorSettingsFromIndex() } override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { EitherT(indexSettingsManager.save(settings)) .leftMap { - case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => SettingsManager.SavingIndexSettingsError.CannotSaveSettings + case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings } .value } - private def attemptLoadingFromIndex(parameters: LoadFromIndexParameters, + private def attemptLoadingFromIndex(loadingAttemptsInterval: LoadingAttemptsInterval, + loadingAttemptsCount: LoadingAttemptsCount, fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { - parameters.loadingAttemptsCount.value.value match { + loadingAttemptsCount.value.value match { case 0 => fallback.map(identity) case attemptsCount => - loadRorSettingsFromIndex(parameters.loadingDelay).flatMap { - case Left(LoadingFromIndexError.IndexNotExist) => - attemptLoadingFromIndex( - parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), - fallback = fallback - ) - case Left(LoadingFromIndexError.IndexUnknownStructure) => - Task.now(Left(LoadingFromIndexError.IndexUnknownStructure)) - case Left(error@LoadingFromIndexError.IndexParsingError(_)) => - Task.now(Left(error)) - case Right(value) => - Task.now(Right(value)) - } + loadRorSettingsFromIndex() + .flatMap { + case Left(LoadingFromIndexError.IndexNotExist) => + for { + _ <- wait(loadingAttemptsInterval.value.value) + result <- attemptLoadingFromIndex( + loadingAttemptsInterval = loadingAttemptsInterval, + loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(loadingAttemptsCount.value.value - 1), + fallback = fallback + ) + } yield result + case Left(LoadingFromIndexError.IndexUnknownStructure) => + Task.now(Left(Right(LoadingFromIndexError.IndexUnknownStructure))) + case Left(error@LoadingFromIndexError.IndexParsingError(_)) => + Task.now(Left(Right(error))) + case Right(value) => + Task.now(Right(value)) + } } } - private def loadRorSettingsFromIndex(loadingDelay: LoadingDelay) = { + private def loadRorSettingsFromIndex() = { val settingsIndex = indexSettingsManager.settingsIndex logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...") - EitherT { - indexSettingsManager - .load() - .delayExecution(loadingDelay.value.value) - } + EitherT(indexSettingsManager.load()) .map { rorSettings => logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw ReadonlyREST settings from index: ${rorSettings.raw.show}") rorSettings @@ -112,24 +123,22 @@ class RorMainSettingsManager private(indexSettingsManager: IndexSettingsManager[ } // todo: these two are almost the same (logging differs only) - private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { - val rorSettingsFile = parameters.rorSettingsFile - val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) - .leftMap { error => - val newError = convertFileError(error) - logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") - newError - } - .value - } - - private def forceLoadFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingFromFileError, RawRorSettings]] = { - val rorSettingsFile = parameters.rorSettingsFile - val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) - logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${rorSettingsFile.show}") - EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) + // private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { + // val rorSettingsFile = parameters.rorSettingsFile + // val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) + // logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") + // EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) + // .leftMap { error => + // val newError = convertFileError(error) + // logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") + // newError + // } + // .value + // } + + private def forceLoadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { + logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${fileSettingsLoader.settingsFile.show}") + EitherT(fileSettingsLoader.load()) .leftMap { error => val newError = convertFileError(error) logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") @@ -162,21 +171,29 @@ class RorMainSettingsManager private(indexSettingsManager: IndexSettingsManager[ logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") } } + + private def wait(duration: FiniteDuration) = { + Task.sleep(duration).map(Right.apply) + } } object RorMainSettingsManager { - def create(esConfigBasedRorSettings: EsConfigBasedRorSettings): RorMainSettingsManager = { - esConfigBasedRorSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => ??? - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => ??? - } - } - - sealed trait LoadingFromFileError extends LoadingError - object LoadingFromFileError { - final case class FileParsingError(message: String) extends LoadingFromFileError - final case class FileNotExist(file: File) extends LoadingFromFileError + type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] + + def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, + indexJsonContentService: IndexJsonContentService): RorMainSettingsManager = { + val rorSettingsFile = esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsFile + val yamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) + new RorMainSettingsManager( + esConfigBasedRorSettings, + new FileRorSettingsLoader(rorSettingsFile, yamlParser), + new IndexJsonContentServiceBasedIndexMainSettingsManager( + esConfigBasedRorSettings.rorSettingsIndex, + yamlParser, + indexJsonContentService, + ) + ) } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala index 5213b6bd12..fa7c247131 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala @@ -19,41 +19,40 @@ package tech.beshu.ror.configuration.manager import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingDelay} -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, TestRorSettings} -import tech.beshu.ror.configuration.index.IndexSettingsManager +import tech.beshu.ror.configuration.RorProperties.LoadingDelay import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} +import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexTestSettingsManager, IndexSettingsManager} +import tech.beshu.ror.configuration.loader.RorSettingsLoader import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingError, LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.implicits.* import scala.language.postfixOps -class RorTestSettingsManager(esConfigBasedRorSettings: EsConfigBasedRorSettings, - fileSettingsLoader: FileRorSettingsLoader, - indexSettingsManager: IndexSettingsManager[TestRorSettings]) - extends SettingsManager[TestRorSettings] with Logging { +class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[TestRorSettings]) + extends InIndexSettingsManager[TestRorSettings] + with Logging { - def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - fallbackSettings: TestRorSettings): Task[Either[LoadingFromIndexError, TestRorSettings]] = { - loadFromIndexWithFallback( - loadFromIndexParameters = loadFromIndexParameters, - fallback = Task.delay(Right(fallbackSettings)) - ).map(_.leftMap { - case error: LoadingFromIndexError => error - case error => throw new IllegalStateException(s"Unexpected $error type") - }) - } - - override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { - attemptLoadingConfigFromIndex( - parameters = loadFromIndexParameters, - fallback = fallback - ) - } + // todo: remove? + // def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + // fallbackSettings: TestRorSettings): Task[Either[LoadingFromIndexError, TestRorSettings]] = { + // loadFromIndexWithFallback( + // loadFromIndexParameters = loadFromIndexParameters, + // fallback = Task.delay(Right(fallbackSettings)) + // ).map(_.leftMap { + // case error: LoadingFromIndexError => error + // case error => throw new IllegalStateException(s"Unexpected $error type") + // }) + // } + // override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, + // fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { + // attemptLoadingConfigFromIndex( + // parameters = loadFromIndexParameters, + // fallback = fallback + // ) + // } override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { loadTestRorConfigFromIndex(LoadingDelay.none) @@ -62,32 +61,33 @@ class RorTestSettingsManager(esConfigBasedRorSettings: EsConfigBasedRorSettings, override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { EitherT(indexSettingsManager.save(settings)) .leftMap { - case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => SettingsManager.SavingIndexSettingsError.CannotSaveSettings + case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings } .value } - private def attemptLoadingConfigFromIndex(parameters: LoadFromIndexParameters, - fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { - parameters.loadingAttemptsCount.value.value match { - case 0 => - fallback - case attemptsCount => - loadTestRorConfigFromIndex(LoadingDelay.none).flatMap { - case Left(LoadingFromIndexError.IndexNotExist) => - attemptLoadingConfigFromIndex( - parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), - fallback = fallback - ) - case Left(error@LoadingFromIndexError.IndexUnknownStructure) => - Task.now(Left(error)) - case Left(error@LoadingFromIndexError.IndexParsingError(_)) => - Task.now(Left(error)) - case Right(value) => - Task.now(Right(value)) - } - } - } + // todo: remove? + // private def attemptLoadingConfigFromIndex(parameters: LoadFromIndexParameters, + // fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { + // parameters.loadingAttemptsCount.value.value match { + // case 0 => + // fallback + // case attemptsCount => + // loadTestRorConfigFromIndex(LoadingDelay.none).flatMap { + // case Left(LoadingFromIndexError.IndexNotExist) => + // attemptLoadingConfigFromIndex( + // parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), + // fallback = fallback + // ) + // case Left(error@LoadingFromIndexError.IndexUnknownStructure) => + // Task.now(Left(error)) + // case Left(error@LoadingFromIndexError.IndexParsingError(_)) => + // Task.now(Left(error)) + // case Right(value) => + // Task.now(Right(value)) + // } + // } + // } private def loadTestRorConfigFromIndex(loadingDelay: LoadingDelay) = { val settingsIndex = indexSettingsManager.settingsIndex @@ -134,3 +134,16 @@ class RorTestSettingsManager(esConfigBasedRorSettings: EsConfigBasedRorSettings, } } +object RorTestSettingsManager { + + def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, + indexJsonContentService: IndexJsonContentService): RorTestSettingsManager = { + new RorTestSettingsManager( + new IndexJsonContentServiceBasedIndexTestSettingsManager( + settingsIndex = esConfigBasedRorSettings.rorSettingsIndex, + indexJsonContentService = indexJsonContentService, + rorSettingsYamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) + ) + ) + } +} diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index ca5f30af60..7621778da9 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -58,8 +58,8 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError. import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError -import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.SettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* From 33b01800d88ac66e399998f8b8f978bf596632f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 15 Jul 2025 16:52:58 +0200 Subject: [PATCH 020/103] refactoring --- .../manager/RorMainSettingsManager.scala | 81 +++++-------- .../manager/RorTestSettingsManager.scala | 106 +++++------------- .../scala/tech/beshu/ror/utils/ScalaOps.scala | 21 +++- 3 files changed, 76 insertions(+), 132 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index 13cb0bdada..9fa9adae43 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -31,11 +31,11 @@ import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.ScalaOps.LoggerOps import scala.concurrent.duration.FiniteDuration import scala.language.postfixOps -// todo: refactor methods class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, fileSettingsLoader: FileRorSettingsLoader, indexSettingsManager: IndexSettingsManager[RawRorSettings]) @@ -63,7 +63,15 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS } override def loadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { - forceLoadFromFile() + val result = for { + _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${fileSettingsLoader.settingsFile.show}")) + settings <- EitherT(fileSettingsLoader.load()) + .leftMap(convertFileError) + .leftSemiflatTap { error => + logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") + } + } yield settings + result.value } override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { @@ -108,43 +116,25 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS private def loadRorSettingsFromIndex() = { val settingsIndex = indexSettingsManager.settingsIndex - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...") - EitherT(indexSettingsManager.load()) - .map { rorSettings => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw ReadonlyREST settings from index: ${rorSettings.raw.show}") - rorSettings - } - .leftMap { error => - val newError = convertIndexError(error) - logIndexLoadingError(newError) - newError - } - .value - } - - // todo: these two are almost the same (logging differs only) - // private def loadRorSettingsFromFile(parameters: LoadFromFileParameters): Task[Either[LoadingError, RawRorSettings]] = { - // val rorSettingsFile = parameters.rorSettingsFile - // val rawRorSettingsYamlParser = new RawRorSettingsYamlParser(parameters.settingsMaxSize) - // logger.info(s"Loading ReadonlyREST settings from file from: ${rorSettingsFile.show}, because index not exist") - // EitherT(new FileRorSettingsLoader(rorSettingsFile, rawRorSettingsYamlParser).load()) - // .leftMap { error => - // val newError = convertFileError(error) - // logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") - // newError - // } - // .value - // } - - private def forceLoadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { - logger.info(s"Loading ReadonlyREST settings forced loading from file from: ${fileSettingsLoader.settingsFile.show}") - EitherT(fileSettingsLoader.load()) - .leftMap { error => - val newError = convertFileError(error) - logger.error(s"Loading ReadonlyREST from file failed: ${newError.toString}") - newError - } - .value + val result = for { + _ <- lift(logger.info(s"Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...")) + settings <- EitherT(indexSettingsManager.load()) + .leftMap(convertIndexError) + .biSemiflatTap( + { + case LoadingFromIndexError.IndexParsingError(message) => + logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") + case LoadingFromIndexError.IndexUnknownStructure => + logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") + case LoadingFromIndexError.IndexNotExist => + logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") + }, + rorSettings => { + logger.dDebug(s"Loaded ReadonlyREST settings from index: ${rorSettings.raw.show}") + } + ) + } yield settings + result.value } private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { @@ -161,20 +151,11 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure } - private def logIndexLoadingError[A](error: LoadingFromIndexError): Unit = { - error match { - case LoadingFromIndexError.IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadingFromIndexError.IndexUnknownStructure => - logger.info(s"Loading ReadonlyREST settings from index failed: index content malformed") - case LoadingFromIndexError.IndexNotExist => - logger.info(s"Loading ReadonlyREST settings from index failed: cannot find index") - } - } - private def wait(duration: FiniteDuration) = { Task.sleep(duration).map(Right.apply) } + + private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) } object RorMainSettingsManager { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala index fa7c247131..0ebce098b6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala @@ -19,7 +19,6 @@ package tech.beshu.ror.configuration.manager import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.RorProperties.LoadingDelay import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexTestSettingsManager, IndexSettingsManager} import tech.beshu.ror.configuration.loader.RorSettingsLoader @@ -28,6 +27,7 @@ import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromI import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.ScalaOps.LoggerOps import scala.language.postfixOps @@ -35,27 +35,30 @@ class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[ extends InIndexSettingsManager[TestRorSettings] with Logging { - // todo: remove? - // def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - // fallbackSettings: TestRorSettings): Task[Either[LoadingFromIndexError, TestRorSettings]] = { - // loadFromIndexWithFallback( - // loadFromIndexParameters = loadFromIndexParameters, - // fallback = Task.delay(Right(fallbackSettings)) - // ).map(_.leftMap { - // case error: LoadingFromIndexError => error - // case error => throw new IllegalStateException(s"Unexpected $error type") - // }) - // } - // override def loadFromIndexWithFallback(loadFromIndexParameters: LoadFromIndexParameters, - // fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { - // attemptLoadingConfigFromIndex( - // parameters = loadFromIndexParameters, - // fallback = fallback - // ) - // } - override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { - loadTestRorConfigFromIndex(LoadingDelay.none) + val settingsIndex = indexSettingsManager.settingsIndex + val result = for { + _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...")) + settings <- EitherT(indexSettingsManager.load()) + .leftMap(convertIndexError) + .biSemiflatTap( + { + case LoadingFromIndexError.IndexParsingError(message) => + logger.dError(s"Loading ReadonlyREST test settings from index failed: ${message.show}") + case LoadingFromIndexError.IndexUnknownStructure => + logger.dInfo("Loading ReadonlyREST test settings from index failed: index content malformed") + case LoadingFromIndexError.IndexNotExist => + logger.dInfo("Loading ReadonlyREST test settings from index failed: cannot find index") + }, + { + case TestRorSettings.Present(rawConfig, _, _) => + logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${rawConfig.raw.show}") + case TestRorSettings.NotSet => + logger.dDebug("There was no ReadonlyREST test settings in the index. Test settings engine will be not initialized.") + } + ) + } yield settings + result.value } override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { @@ -66,55 +69,6 @@ class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[ .value } - // todo: remove? - // private def attemptLoadingConfigFromIndex(parameters: LoadFromIndexParameters, - // fallback: Task[Either[LoadingError, TestRorSettings]]): Task[Either[LoadingError, TestRorSettings]] = { - // parameters.loadingAttemptsCount.value.value match { - // case 0 => - // fallback - // case attemptsCount => - // loadTestRorConfigFromIndex(LoadingDelay.none).flatMap { - // case Left(LoadingFromIndexError.IndexNotExist) => - // attemptLoadingConfigFromIndex( - // parameters.copy(loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(parameters.loadingAttemptsCount.value.value - 1)), - // fallback = fallback - // ) - // case Left(error@LoadingFromIndexError.IndexUnknownStructure) => - // Task.now(Left(error)) - // case Left(error@LoadingFromIndexError.IndexParsingError(_)) => - // Task.now(Left(error)) - // case Right(value) => - // Task.now(Right(value)) - // } - // } - // } - - private def loadTestRorConfigFromIndex(loadingDelay: LoadingDelay) = { - val settingsIndex = indexSettingsManager.settingsIndex - // todo: log is ok? - logger.info(s"[CLUSTERWIDE SETTINGS] Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...") - EitherT { - indexSettingsManager - .load() - .delayExecution(loadingDelay.value.value) - } - .map { testConfig => - testConfig match { - case TestRorSettings.Present(rawConfig, _, _) => - logger.debug(s"[CLUSTERWIDE SETTINGS] Loaded raw test config from index: ${rawConfig.raw.show}") - case TestRorSettings.NotSet => - logger.debug("[CLUSTERWIDE SETTINGS] There was no test settings in index. Test settings engine will be not initialized.") - } - testConfig - } - .leftMap { error => - val newError = convertIndexError(error) - logIndexLoadingError(newError) - newError - } - .value - } - private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingFromIndexError = error match { case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) @@ -122,17 +76,7 @@ class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[ case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure } - private def logIndexLoadingError(error: LoadingFromIndexError): Unit = { - error match { - case LoadingFromIndexError.IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadingFromIndexError.IndexUnknownStructure => - logger.info("Loading ReadonlyREST test settings from index failed: index content malformed") - case LoadingFromIndexError.IndexNotExist => - logger.info("Loading ReadonlyREST test settings from index failed: cannot find index") - } - } - + private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) } object RorTestSettingsManager { diff --git a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala index 5aa99ce6f7..b52ad7dca9 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala @@ -24,6 +24,7 @@ import eu.timepit.refined.api.Refined import eu.timepit.refined.types.string.NonEmptyString import monix.eval.Task import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logger import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -237,10 +238,28 @@ object ScalaOps { } } - implicit class PositiveFiniteDurationAdd(duration: PositiveFiniteDuration) extends AnyVal { + implicit class PositiveFiniteDurationAdd(val duration: PositiveFiniteDuration) extends AnyVal { def +(duration: PositiveFiniteDuration): PositiveFiniteDuration = { Refined.unsafeApply(this.duration.value + duration.value) } } + + implicit class LoggerOps(val logger: Logger) extends AnyVal { + def dInfo(msg: String): Task[Unit] = { + Task.delay(logger.info(msg)) + } + + def dWarn(msg: String): Task[Unit] = { + Task.delay(logger.warn(msg)) + } + + def dDebug(msg: String): Task[Unit] = { + Task.delay(logger.debug(msg)) + } + + def dError(msg: String): Task[Unit] = { + Task.delay(logger.error(msg)) + } + } } From a36e8495c83da888fb8bd515efcf5515ea5a8848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 15 Jul 2025 18:09:03 +0200 Subject: [PATCH 021/103] refactoring --- .../EsConfigBasedRorSettings.scala | 2 +- .../ror/configuration/RorSslSettings.scala | 9 +- .../manager/RorMainSettingsManager.scala | 25 ++- .../scala/tech/beshu/ror/utils/ScalaOps.scala | 4 +- .../unit/boot/ReadonlyRestStartingTests.scala | 32 ++-- .../beshu/ror/unit/boot/RorIndexTest.scala | 10 +- .../LoadRawRorSettingsTest.scala | 4 - .../configuration/RorBootSettingsTest.scala | 3 +- .../configuration/SslConfigurationTest.scala | 3 +- .../configuration/loader/ResultDTOTest.scala | 82 --------- .../configuration/loader/SummaryTest.scala | 174 ------------------ 11 files changed, 58 insertions(+), 290 deletions(-) delete mode 100644 core/src/test/scala/tech/beshu/ror/unit/configuration/loader/ResultDTOTest.scala delete mode 100644 core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index 2e9dedc286..bd0d06d698 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -82,7 +82,7 @@ object EsConfigBasedRorSettings { rorSettingsFromFileParameters: LoadFromFileParameters, xpackSecurity: XpackSecurity) (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { - EitherT(RorSslSettings.load(esEnv, rorSettingsFromFileParameters)) + EitherT(RorSslSettings.load(rorSettingsFromFileParameters.rorSettingsFile, esEnv.elasticsearchYmlFile)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) .subflatMap { case Some(ssl) if xpackSecurity.enabled => diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala index 3c7719ab90..103b95e3b0 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala @@ -22,9 +22,7 @@ import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromFileParameters import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslSettings, FipsMode, InternodeSslSettings} -import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.SSLCertHelper @@ -58,17 +56,16 @@ object RorSslSettings extends Logging { } } - def load(esEnv: EsEnv, loadFromFileParameters: LoadFromFileParameters) + def load(rorSettingsFile: File, esConfigFile: File) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = Task { - implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esEnv.configDir) - val esConfigFile = esEnv.elasticsearchYmlFile + implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esConfigFile.parent) loadSslSettingsFrom(esConfigFile) .fold( error => Left(error), { case None => logger.info(s"Cannot find ROR SSL settings in ${esConfigFile.show} ...") - fallbackToRorSettingsFile(loadFromFileParameters.rorSettingsFile) + fallbackToRorSettingsFile(rorSettingsFile) case Some(ssl) => Right(Some(ssl)) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index 9fa9adae43..d7e8c960f3 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -38,7 +38,8 @@ import scala.language.postfixOps class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, fileSettingsLoader: FileRorSettingsLoader, - indexSettingsManager: IndexSettingsManager[RawRorSettings]) + indexSettingsManager: IndexSettingsManager[RawRorSettings], + indexJsonContentService: IndexJsonContentService) extends FileSettingsManager[RawRorSettings] with InIndexSettingsManager[RawRorSettings] with Logging { @@ -137,6 +138,28 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS result.value } + private def loadSettingsFromIndex() = { + indexJsonContentService + .sourceOf(settingsIndex.index, Const.id) + .flatMap { + case Right(source) => + source + .find(_._1 == Const.settingsKey) + .map { case (_, rorYamlString) => + rorSettingsYamlParser + .fromString(rorYamlString) + .map(_.left.map(ParsingError.apply)) + } + .getOrElse { + settingsLoaderError(UnknownStructureOfIndexDocument) + } + case Left(CannotReachContentSource) => + settingsLoaderError(IndexNotExist) + case Left(ContentNotFound) => + settingsLoaderError(IndexNotExist) + } + } + private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { error match { case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) diff --git a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala index b52ad7dca9..07704dfbf9 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala @@ -238,14 +238,14 @@ object ScalaOps { } } - implicit class PositiveFiniteDurationAdd(val duration: PositiveFiniteDuration) extends AnyVal { + implicit class PositiveFiniteDurationAdd(duration: PositiveFiniteDuration) extends AnyVal { def +(duration: PositiveFiniteDuration): PositiveFiniteDuration = { Refined.unsafeApply(this.duration.value + duration.value) } } - implicit class LoggerOps(val logger: Logger) extends AnyVal { + implicit class LoggerOps(logger: Logger) { def dInfo(msg: String): Task[Unit] = { Task.delay(logger.info(msg)) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 5a549f6afa..53cf722f4e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -29,6 +29,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.time.{Millis, Seconds, Span} import org.scalatest.wordspec.AnyWordSpec import org.scalatest.{EitherValues, Inside, OptionValues} +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext import tech.beshu.ror.accesscontrol.audit.AuditingTool @@ -40,14 +41,14 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenti import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} +import tech.beshu.ror.accesscontrol.factory.RorDependencies.NoOpImpersonationWarningsReader +import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.RorDependencies.NoOpImpersonationWarningsReader -import tech.beshu.ror.configuration.index.SavingIndexConfigError -import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound, WriteError} @@ -181,7 +182,7 @@ class ReadonlyRestStartingTests createCoreResult = Task .sleep(100 millis) - .map(_ => Right(Core(mockEnabledAccessControl, RorDependencies.noOp))) // very long creation + .map(_ => Right(Core(mockEnabledAccessControl, RorDependencies.noOp, None))) // very long creation ) mockIndexJsonContentManagerSaveCall( mockedIndexJsonContentManager, @@ -415,7 +416,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) + mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) (readonlyRest, expirationTimestamp) @@ -597,7 +598,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) + mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) (readonlyRest, mockedIndexJsonContentManager) @@ -1285,7 +1286,7 @@ class ReadonlyRestStartingTests .returns(Task.now(Left(CannotWriteToIndex))) rorInstance.invalidateTestSettingsEngine()(newRequestId()).runSyncUnsafe() should be( - Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingIndexConfigError.CannotSaveConfig)) + Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveConfig)) ) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -1324,7 +1325,8 @@ class ReadonlyRestStartingTests mock[CoreFactory], "/boot_tests/forced_file_loading_with_audit/readonlyrest.yml", mockEnabledAccessControl, - RorConfig(RorDependencies.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader, Some(AuditingTool.Settings( + RorDependencies(RorDependencies.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader), + Some(AuditingTool.Settings( NonEmptyList.of( AuditSink.Enabled(dataStreamSinkConfig1), AuditSink.Enabled(dataStreamSinkConfig2)) @@ -1409,7 +1411,7 @@ class ReadonlyRestStartingTests .map(size => "com.readonlyrest.settings.maxSize" -> size) .toMap - implicit val systemContext: SystemContext = new Environment( + implicit val systemContext: SystemContext = new SystemContext( propertiesProvider = TestsPropertiesProvider.usingMap( mapWithIntervalFrom(refreshInterval) ++ mapWithMaxYamlSize(maxYamlSize) ++ @@ -1461,20 +1463,22 @@ class ReadonlyRestStartingTests private def mockCoreFactory(mockedCoreFactory: CoreFactory, resourceFileName: String, accessControlMock: AccessControlList = mockEnabledAccessControl, - dependencies: RorDependencies = RorDependencies.noOp): CoreFactory = { - mockCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName), accessControlMock, dependencies) + dependencies: RorDependencies = RorDependencies.noOp, + auditingSettings: Option[AuditingTool.Settings] = None): CoreFactory = { + mockCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName), accessControlMock, dependencies, auditingSettings) } private def mockCoreFactory(mockedCoreFactory: CoreFactory, rawRorConfig: RawRorSettings, accessControlMock: AccessControlList, - dependencies: RorDependencies): CoreFactory = { + dependencies: RorDependencies, + auditingSettings: Option[AuditingTool.Settings]): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { (config: RawRorSettings, _, _, _, _) => config == rawRorConfig }) .once() - .returns(Task.now(Right(Core(accessControlMock, dependencies)))) + .returns(Task.now(Right(Core(accessControlMock, dependencies, auditingSettings)))) mockedCoreFactory } diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index a7cc32e610..a20693d287 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -24,14 +24,15 @@ import org.scalatest.concurrent.Eventually import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import org.scalatest.{EitherValues, Inside, OptionValues} +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId} -import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory} +import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.boot.RorInstance.TestSettings import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -42,6 +43,7 @@ import java.util.UUID import scala.concurrent.duration.* import scala.language.postfixOps +// todo: change name class RorIndexTest extends AnyWordSpec with Inside with OptionValues with EitherValues with MockFactory with Eventually { @@ -217,7 +219,7 @@ class RorIndexTest extends AnyWordSpec private def readonlyRestBoot(factory: CoreFactory, indexJsonContentService: IndexJsonContentService, configPath: String) = { - implicit val systemContext: SystemContext = new Environment( + implicit val systemContext: SystemContext = new SystemContext( propertiesProvider = TestsPropertiesProvider.usingMap( Map( "com.readonlyrest.settings.loading.delay" -> "1" @@ -240,7 +242,7 @@ class RorIndexTest extends AnyWordSpec (config: RawRorSettings, _, _, _, _) => config == rawRorConfig }) .once() - .returns(Task.now(Right(Core(mockAccessControl, RorDependencies.noOp)))) + .returns(Task.now(Right(Core(mockAccessControl, RorDependencies.noOp, None)))) mockedCoreFactory } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala index 85c28f9a43..e613e9ed12 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala @@ -22,12 +22,8 @@ import org.scalatest.EitherValues import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} -import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction -import tech.beshu.ror.configuration.RorConfigLoading.LoadRorConfigAction.* import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} -import tech.beshu.ror.configuration.loader.LoadedRorConfig.{FileConfig, ForcedFileConfig, IndexConfig} -import tech.beshu.ror.configuration.loader.{RorMainSettingsManager, LoadedRorConfig} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, unsafeNes} diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala index bbade9837d..c15f5e08df 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala @@ -20,8 +20,9 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} -import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorBootSettings} +import tech.beshu.ror.configuration.{MalformedSettings, RorBootSettings} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala index 95f1a8aa14..9f89fee14e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala @@ -20,6 +20,7 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.configuration.SslConfiguration.* import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorSslSettings} @@ -30,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePat class SslConfigurationTest extends AnyWordSpec with Inside { - private implicit val systemContext: SystemContext = new Environment( + private implicit val systemContext: SystemContext = new SystemContext( propertiesProvider = TestsPropertiesProvider.default ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/ResultDTOTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/ResultDTOTest.scala deleted file mode 100644 index 612457a224..0000000000 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/ResultDTOTest.scala +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.unit.configuration.loader - -import cats.implicits.* -import io.circe.syntax.* -import org.scalatest.matchers.should.Matchers.* -import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.configuration.loader.distributed.{NodesResponse, Summary} -import tech.beshu.ror.configuration.loader.external.dto.{LoadedConfigDTO, NodesResponseWaringDTO, ResultDTO} - -import scala.language.postfixOps - -class ResultDTOTest extends AnyWordSpec { - "ResultDTO" when { - "result failed" should { - "return current node " in { - val expectedResult = ResultDTO(None, Nil, "current node returned error: index unknown structure" some) - ResultDTO.create(Summary.CurrentNodeConfigError(LoadedRorConfig.IndexUnknownStructure) asLeft) shouldEqual expectedResult - } - "return current node failure" in { - val expectedResult = ResultDTO(None, Nil, "current node response error: null pointer" some) - ResultDTO.create(Summary.CurrentNodeResponseError("null pointer") asLeft) shouldEqual expectedResult - } - } - "return result" should { - val warnings = Summary.NodeReturnedConfigError(NodesResponse.NodeId("n2"), LoadedRorConfig.IndexUnknownStructure) :: - Summary.NodeForcedFileConfig(NodesResponse.NodeId("n1")) :: - Nil - val result = ResultDTO.create(Summary.Result(LoadedRorConfig.ForcedFileConfig("config"), warnings) asRight) - "be as DTO" in { - val expectedResult = ResultDTO( - config = LoadedConfigDTO.FORCED_FILE_CONFIG("config").some, - warnings = NodesResponseWaringDTO.NODE_RETURNED_CONFIG_ERROR("n2", "index unknown structure") :: - NodesResponseWaringDTO.NODE_FORCED_FILE_CONFIG("n1") :: - Nil, - error = None, - ) - result shouldEqual expectedResult - } - "be as JSON" in { - val expectedResult = - """ - |{ - | "config" : { - | "raw" : "config", - | "type" : "FORCED_FILE_CONFIG" - | }, - | "warnings" : [ - | { - | "nodeId" : "n2", - | "error" : "index unknown structure", - | "type" : "NODE_RETURNED_CONFIG_ERROR" - | }, - | { - | "nodeId" : "n1", - | "type" : "NODE_FORCED_FILE_CONFIG" - | } - | ], - | "error" : null - |}""".stripMargin - result.asJson shouldEqual io.circe.parser.parse(expectedResult).toTry.get - } - } - } - -} diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala deleted file mode 100644 index b96da1ac02..0000000000 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/loader/SummaryTest.scala +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.unit.configuration.loader - -import cats.implicits.* -import eu.timepit.refined.types.string.NonEmptyString -import org.scalatest.matchers.should.Matchers.* -import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} -import tech.beshu.ror.configuration.loader.LoadedRorConfig -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.configuration.loader.distributed.Summary.CurrentNodeHaveToProduceResult -import tech.beshu.ror.configuration.loader.distributed.{NodesResponse, Summary} -import tech.beshu.ror.utils.TestsUtils.unsafeNes - -import scala.language.postfixOps - -class SummaryTest extends AnyWordSpec { - "Summary" when { - "there are no configs" should { - "throw exception, current node have to give response" in { - assertThrows[CurrentNodeHaveToProduceResult.type] { - Summary.create(NodeId(""), Nil, Nil) - } - } - } - "there is no current node config" should { - "throw no current node config error" in { - assertThrows[CurrentNodeHaveToProduceResult.type] { - val conf = LoadedRorConfig.IndexConfig(configIndex("config-index"), "config") - Summary.create(NodeId(""), NodeResponse(NodeId("b"), conf asRight) :: Nil, Nil) - } - } - } - "current node has no ror" should { - "throw error" in { - assertThrows[CurrentNodeHaveToProduceResult.type] { - Summary.create(NodeId("a"), Nil, NodeError(NodeId("a"), NodeError.RorConfigActionNotFound) :: Nil) - } - } - } - "current node has some error" should { - "throw error" in { - Summary.create( - currentNodeId = NodeId("a"), - nodesResponses = Nil, - failures = NodeError(NodeId("a"), NodeError.Unknown("exception message")) :: Nil, - ) shouldEqual - Summary.CurrentNodeResponseError("exception message").asLeft - } - } - "only node returns config" should { - "return current node config" in { - val conf = LoadedRorConfig.IndexConfig(configIndex("config-index"), "config") - Summary.create(NodeId("a"), NodeResponse(NodeId("a"), conf asRight) :: Nil, Nil) shouldBe - Summary.Result(conf, Nil).asRight - } - } - "only node returns error" should { - "return that error" in { - Summary.create( - currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), LoadedRorConfig.IndexUnknownStructure asLeft) :: Nil, - failures = Nil, - ) shouldBe - Summary.CurrentNodeConfigError(LoadedRorConfig.IndexUnknownStructure).asLeft - } - } - "current node returns error" should { - "return that error" in { - Summary.create( - currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), LoadedRorConfig.IndexUnknownStructure asLeft) :: - NodeResponse(NodeId("b"), LoadedRorConfig.IndexConfig(configIndex("config-index"), "config") asRight) :: - Nil, - failures = Nil, - ) shouldBe - Summary.CurrentNodeConfigError(LoadedRorConfig.IndexUnknownStructure).asLeft - } - } - "other node returns error" should { - "return config, and other node error as warning" in { - val conf = LoadedRorConfig.IndexConfig(configIndex("config-index"), "config") - Summary.create( - currentNodeId = NodeId("b"), - nodesResponses = NodeResponse(NodeId("a"), LoadedRorConfig.IndexUnknownStructure asLeft) :: - NodeResponse(NodeId("b"), conf asRight) :: - Nil, - failures = Nil, - ) shouldBe - Summary.Result(config = conf, - warnings = Summary.NodeReturnedConfigError(NodeId("a"), LoadedRorConfig.IndexUnknownStructure) :: Nil, - ).asRight - } - } - "current node is force loaded from file" should { - "return config, and forced loading from file as warning" in { - val conf = LoadedRorConfig.ForcedFileConfig("config") - Summary.create(NodeId("a"), NodeResponse(NodeId("a"), conf asRight) :: Nil, Nil) shouldBe - Summary.Result(conf, Summary.NodeForcedFileConfig(NodeId("a")) :: Nil).asRight - } - } - "other node returned unknown error" should { - "return config, and unknown error warning" in { - val conf = LoadedRorConfig.ForcedFileConfig("config") - Summary.create( - currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), conf asRight) :: Nil, - failures = NodeError(NodeId("b"), NodeError.Unknown("detailed message")) :: Nil, - ) shouldBe - Summary.Result(config = conf, - warnings = Summary.NodeForcedFileConfig(NodeId("a")) :: - Summary.NodeReturnedUnknownError(NodeId("b"), "detailed message") :: - Nil, - ).asRight - } - } - "other node returned action not found" should { - "ignore action not found error" in { - val conf = LoadedRorConfig.ForcedFileConfig("config") - Summary.create(currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), conf asRight) :: Nil, - failures = NodeError(NodeId("b"), NodeError.RorConfigActionNotFound) :: Nil, - ) shouldBe - Summary.Result(conf, Summary.NodeForcedFileConfig(NodeId("a")) :: Nil).asRight - } - } - "current node returned timeout" should { - "return error" in { - Summary.create(NodeId("a"), Nil, NodeError(NodeId("a"), NodeError.Timeout) :: Nil) shouldBe - Summary.CurrentNodeResponseTimeoutError.asLeft - } - } - "other node has timeout" should { - "return config, and warning" in { - val currentConfig = LoadedRorConfig.FileConfig("config1") - Summary.create(currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), currentConfig asRight) :: Nil, - failures = NodeError(NodeId("b"), NodesResponse.NodeError.Timeout) :: Nil, - ) shouldBe - Summary.Result(currentConfig, Summary.NodeResponseTimeoutWarning(NodeId("b")) :: Nil).asRight - } - } - "other node has different config, than current node" should { - "return config, and warning" in { - val currentConfig = LoadedRorConfig.FileConfig("config1") - val otherConfig = LoadedRorConfig.FileConfig("config2") - Summary.create( - currentNodeId = NodeId("a"), - nodesResponses = NodeResponse(NodeId("a"), currentConfig asRight) :: - NodeResponse(NodeId("b"), otherConfig asRight) :: - Nil, failures = Nil, - ) shouldBe - Summary.Result(currentConfig, Summary.NodeReturnedDifferentConfig(NodeId("b"), otherConfig) :: Nil).asRight - } - } - } - - private def configIndex(value: NonEmptyString) = RorSettingsIndex(IndexName.Full(value)) -} From 5aded82b333393ea0c6a109da26d327b84d66f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 29 Jul 2025 13:08:00 +0200 Subject: [PATCH 022/103] wip --- .../manager/RorMainSettingsManager.scala | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index d7e8c960f3..b6a07181be 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -38,8 +38,7 @@ import scala.language.postfixOps class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, fileSettingsLoader: FileRorSettingsLoader, - indexSettingsManager: IndexSettingsManager[RawRorSettings], - indexJsonContentService: IndexJsonContentService) + indexSettingsManager: IndexSettingsManager[RawRorSettings]) extends FileSettingsManager[RawRorSettings] with InIndexSettingsManager[RawRorSettings] with Logging { @@ -138,28 +137,6 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS result.value } - private def loadSettingsFromIndex() = { - indexJsonContentService - .sourceOf(settingsIndex.index, Const.id) - .flatMap { - case Right(source) => - source - .find(_._1 == Const.settingsKey) - .map { case (_, rorYamlString) => - rorSettingsYamlParser - .fromString(rorYamlString) - .map(_.left.map(ParsingError.apply)) - } - .getOrElse { - settingsLoaderError(UnknownStructureOfIndexDocument) - } - case Left(CannotReachContentSource) => - settingsLoaderError(IndexNotExist) - case Left(ContentNotFound) => - settingsLoaderError(IndexNotExist) - } - } - private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { error match { case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) @@ -167,7 +144,7 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS } } - private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]) = + private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]): LoadingFromIndexError = error match { case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist @@ -178,7 +155,7 @@ class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorS Task.sleep(duration).map(Right.apply) } - private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) + private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) } object RorMainSettingsManager { From b37ae1b2411b949bea5fd91615592d69d334fbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 13 Aug 2025 08:39:03 +0200 Subject: [PATCH 023/103] wip --- .../MainSettingsBasedReloadableEngine.scala | 2 +- .../ror/settings/FileSettingsSource.scala | 58 +++++++++++++++++++ .../ror/settings/IndexSettingsSource.scala | 29 ++++++++++ .../beshu/ror/settings/SettingsSource.scala | 45 ++++++++++++++ .../scala/tech/beshu/ror/utils/ScalaOps.scala | 1 - 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 0bccea08f6..d9af64a783 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -30,7 +30,7 @@ import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.manager.RorMainSettingsManager -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.ScalaOps.value diff --git a/core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala new file mode 100644 index 0000000000..5153c2cc9f --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala @@ -0,0 +1,58 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings + +import better.files.File +import cats.data.EitherT +import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} +import monix.eval.Task +import tech.beshu.ror.settings.FileSettingsSource.LoadingError.FileNotExist +import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError + +class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) + extends ReadOnlySettingsSource[SETTINGS] { + + override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = { + (for { + _ <- checkIfFileExist(rorSettingsFile) + settings <- loadSettingsFromFile(rorSettingsFile) + } yield settings).value + } + + private def checkIfFileExist(file: File): EitherT[Task, LoadingSettingsError, File] = + EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) + + private def loadSettingsFromFile(file: File): EitherT[Task, LoadingSettingsError, SETTINGS] = { + EitherT + .pure[Task, LoadingSettingsError](file.contentAsString) + .subflatMap { raw => + parser + .decode(raw) + .left.map { + case ParsingFailure(_, _) => LoadingSettingsError.FormatError + case _: DecodingFailure => LoadingSettingsError.FormatError + } + } + } +} +object FileSettingsSource { + sealed trait LoadingError + object LoadingError { + final case class FileNotExist(file: File) extends LoadingError + } +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala new file mode 100644 index 0000000000..6204171989 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala @@ -0,0 +1,29 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings + +import io.circe.{Decoder, Encoder} +import monix.eval.Task +import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex + +class IndexSettingsSource[SETTINGS : Encoder : Decoder](settingsIndex: RorSettingsIndex) + extends ReadWriteSettingsSource[SETTINGS] { + + override def save(config: SETTINGS): Task[Either[ReadWriteSettingsSource.SavingSettingsError, Unit]] = ??? + + override def load(): Task[Either[ReadOnlySettingsSource.LoadingSettingsError, SETTINGS]] = ??? +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala new file mode 100644 index 0000000000..58b67dc392 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings + +import io.circe.{Decoder, Encoder} +import monix.eval.Task +import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ReadWriteSettingsSource.SavingSettingsError + +sealed trait SettingsSource[SETTINGS] + +trait ReadOnlySettingsSource[SETTINGS : Decoder] extends SettingsSource[SETTINGS] { + def load(): Task[Either[LoadingSettingsError, SETTINGS]] +} +object ReadOnlySettingsSource { + sealed trait LoadingSettingsError + object LoadingSettingsError { + case object FormatError extends LoadingSettingsError + final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError + } +} + +trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder] extends ReadOnlySettingsSource[SETTINGS] { + def save(config: SETTINGS): Task[Either[SavingSettingsError, Unit]] +} +object ReadWriteSettingsSource { + sealed trait SavingSettingsError + object SavingSettingsError { + final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError + } +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala index 07704dfbf9..1adcd5e5aa 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala @@ -28,7 +28,6 @@ import org.apache.logging.log4j.scala.Logger import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration -import java.util import java.util.Base64 import scala.collection.immutable.SortedSet import scala.concurrent.duration.* From 9e79f6c5cd436326970e7a8180b90a377467e66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 29 Aug 2025 18:05:17 +0200 Subject: [PATCH 024/103] wip --- .gitignore | 1 + .../beshu/ror/api/MainRorSettingsApi.scala | 19 ++++---- .../tech/beshu/ror/boot/ReadonlyRest.scala | 46 ++++++++++--------- .../tech/beshu/ror/boot/RorInstance.scala | 37 +++++++-------- .../boot/engines/BaseReloadableEngine.scala | 6 ++- .../MainSettingsBasedReloadableEngine.scala | 17 ++++--- .../TestSettingsBasedReloadableEngine.scala | 15 +++--- .../{ => source}/FileSettingsSource.scala | 8 ++-- .../{ => source}/IndexSettingsSource.scala | 8 ++-- .../{ => source}/SettingsSource.scala | 15 ++++-- ...rMainSettingsFileOnlyLoadingStrategy.scala | 28 +++++++++++ ...IndexWithFileFallbackLoadingStrategy.scala | 38 +++++++++++++++ ...TestSettingsIndexOnlyLoadingStrategy.scala | 28 +++++++++++ .../strategy/SettingsLoadingStrategy.scala | 24 ++++++++++ 14 files changed, 212 insertions(+), 78 deletions(-) rename core/src/main/scala/tech/beshu/ror/settings/{ => source}/FileSettingsSource.scala (86%) rename core/src/main/scala/tech/beshu/ror/settings/{ => source}/IndexSettingsSource.scala (73%) rename core/src/main/scala/tech/beshu/ror/settings/{ => source}/SettingsSource.scala (73%) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala diff --git a/.gitignore b/.gitignore index 4159741d22..f9a03dbe12 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ target/ .travis/secret.pgp .java-version +.sdkmanrc // docker-envs builds/* diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index dbda9f1b1e..c8c66e400c 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -29,15 +29,15 @@ import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.manager.RorMainSettingsManager -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class MainRorSettingsApi(rorInstance: RorInstance, settingsYamlParser: RawRorSettingsYamlParser, - settingsManager: RorMainSettingsManager) + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings]) extends Logging { import MainRorSettingsApi.Utils.* @@ -85,8 +85,8 @@ class MainRorSettingsApi(rorInstance: RorInstance, } private def provideRorFileSettings(): Task[MainSettingsResponse] = { - settingsManager - .loadFromFile() + mainSettingsFileSource + .load() .map { case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) case Left(error) => ProvideFileMainSettings.Failure(error.show) @@ -94,13 +94,14 @@ class MainRorSettingsApi(rorInstance: RorInstance, } private def provideRorIndexSettings(): Task[MainSettingsResponse] = { - settingsManager - .loadFromIndex() + mainSettingsIndexSource + .load() .map { case Right(settings) => ProvideIndexMainSettings.MainSettings(settings.raw) - case Left(error@LoadingFromIndexError.IndexNotExist) => - ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) + // todo: ??? +// case Left(error@LoadingFromIndexError.IndexNotExist) => +// ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) case Left(error) => ProvideIndexMainSettings.Failure(error.show) } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index ec3d9e7830..adf4441823 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -35,11 +35,11 @@ import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.manager.* -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError -import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, RorTestSettingsIndexOnlyLoadingStrategy} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant @@ -56,37 +56,41 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - rorMainSettingsManager <- lift(RorMainSettingsManager.create(esConfig, indexContentService)) - rorTestSettingsManager <- lift(RorTestSettingsManager.create(esConfig, indexContentService)) - loadedMainRorSettings <- loadMainSettingsAccordingToStrategy(rorMainSettingsManager) - loadedTestRorSettings <- loadRorTestSettings(esConfig, rorTestSettingsManager) - instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsManager, loadedTestRorSettings, rorTestSettingsManager) + rorMainSettingsLoader <- lift(new RorMainSettingsIndexWithFileFallbackLoadingStrategy(???, ???)) + rorTestSettingsLoader <- lift(new RorTestSettingsIndexOnlyLoadingStrategy(???)) + loadedMainRorSettings <- loadMainSettings(rorMainSettingsLoader) + loadedTestRorSettings <- loadTestSettings(esConfig, rorTestSettingsLoader) + instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsLoader, loadedTestRorSettings, rorTestSettingsLoader) } yield instance).value } - private def loadMainSettingsAccordingToStrategy(rorSettingsLoader: RorMainSettingsManager): EitherT[Task, StartingFailure, RawRorSettings] = { - EitherT(rorSettingsLoader.loadAccordingToStrategy()) + private def loadMainSettings(rorSettingsLoader: RorMainSettingsIndexWithFileFallbackLoadingStrategy): EitherT[Task, StartingFailure, RawRorSettings] = { + EitherT(rorSettingsLoader.load()) .leftMap(toStartingFailure) } - private def loadRorTestSettings(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorTestSettingsManager): EitherT[Task, StartingFailure, TestRorSettings] = { + private def loadTestSettings(esConfig: EsConfigBasedRorSettings, + rorSettingsLoader: RorTestSettingsIndexOnlyLoadingStrategy): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => EitherT { - rorSettingsLoader.loadFromIndex() + rorSettingsLoader.load() }.leftFlatMap { - case LoadingFromIndexError.IndexParsingError(message) => - logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - case LoadingFromIndexError.IndexUnknownStructure => - logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - case LoadingFromIndexError.IndexNotExist => - logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + e => + e match { + case LoadingSettingsError.FormatError => ??? + } +// case LoadingFromIndexError.IndexParsingError(message) => +// logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") +// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) +// case LoadingFromIndexError.IndexUnknownStructure => +// logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") +// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) +// case LoadingFromIndexError.IndexNotExist => +// logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") +// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index badb7042d5..b1ed099eab 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -32,10 +32,10 @@ import tech.beshu.ror.api.{AuthMockApi, MainRorSettingsApi, TestRorSettingsApi} import tech.beshu.ror.boot.engines.{Engines, MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.manager.{RorMainSettingsManager, RorTestSettingsManager} -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant @@ -45,10 +45,11 @@ class RorInstance private(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, mainInitialEngine: ReadonlyRest.MainEngine, mainReloadInProgress: Semaphore[Task], - mainSettingsManager: RorMainSettingsManager, + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], testInitialEngine: ReadonlyRest.TestEngine, testReloadInProgress: Semaphore[Task], - testSettingsManager: RorTestSettingsManager) + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -70,19 +71,19 @@ class RorInstance private(boot: ReadonlyRest, esConfig, (mainInitialEngine.engine, mainInitialEngine.settings), mainReloadInProgress, - mainSettingsManager + mainSettingsIndexSource ) private val theTestSettingsEngine = TestSettingsBasedReloadableEngine.create( boot, esConfig, testInitialEngine, testReloadInProgress, - testSettingsManager + testSettingsIndexSource ) private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize) - private val mainSettingsRestApi = new MainRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser, mainSettingsManager) + private val mainSettingsRestApi = new MainRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser, mainSettingsIndexSource, mainSettingsFileSource) private val testSettingsRestApi = new TestRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser) private val authMockRestApi = new AuthMockApi(rorInstance = this) @@ -216,8 +217,8 @@ object RorInstance { esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: RorMainSettingsManager, - testSettingsManager: RorTestSettingsManager) + mainSettingsManager: IndexSettingsSource[RawRorSettings], + testSettingsManager: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { esConfig.loadingRorCoreStrategy match { @@ -233,8 +234,8 @@ object RorInstance { mode: RorInstance.Mode, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: RorMainSettingsManager, - testSettingsManager: RorTestSettingsManager) + mainSettingsManager: IndexSettingsSource[RawRorSettings], + testSettingsManager: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { @@ -246,10 +247,10 @@ object RorInstance { mode = mode, mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, - mainSettingsManager = mainSettingsManager, + mainSettingsIndexSource = mainSettingsManager, testInitialEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, - testSettingsManager = testSettingsManager + testSettingsIndexSource = testSettingsManager ) } @@ -263,25 +264,25 @@ object RorInstance { sealed trait IndexSettingsReloadWithUpdateError object IndexSettingsReloadWithUpdateError { final case class ReloadError(undefined: RawSettingsReloadError) extends IndexSettingsReloadWithUpdateError - final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsReloadWithUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsReloadWithUpdateError } sealed trait IndexSettingsReloadError object IndexSettingsReloadError { - final case class LoadingSettingsError(underlying: LoadingFromIndexError) extends IndexSettingsReloadError + final case class LoadingSettingsError(underlying: LoadingSettingsError) extends IndexSettingsReloadError final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError } sealed trait IndexSettingsUpdateError object IndexSettingsUpdateError { - final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsUpdateError case object TestSettingsNotSet extends IndexSettingsUpdateError case object TestSettingsInvalidated extends IndexSettingsUpdateError } sealed trait IndexSettingsInvalidationError object IndexSettingsInvalidationError { - final case class IndexSettingsSavingError(underlying: SavingIndexSettingsError) extends IndexSettingsInvalidationError + final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsInvalidationError } private sealed trait ScheduledReloadError diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index effa4f1faf..1d9b4c3bf8 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -421,9 +421,11 @@ private[engines] abstract class BaseReloadableEngine(val name: String, object BaseReloadableEngine { - private[engines] sealed trait InitialEngine + //private[engines] // todo: uncomment + sealed trait InitialEngine - private[engines] object InitialEngine { + //private[engines] // todo: uncomment + object InitialEngine { case object NotConfigured extends InitialEngine final case class Configured(engine: Engine, settings: RawRorSettings, diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index d9af64a783..a3138e24a5 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -29,17 +29,16 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.manager.RorMainSettingsManager -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, esConfig: EsConfigBasedRorSettings, initialEngine: (Engine, RawRorSettings), reloadInProgress: Semaphore[Task], - settingsManager: RorMainSettingsManager) + settingsSource: IndexSettingsSource[RawRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine( @@ -120,14 +119,14 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, result.value } - private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { - EitherT(settingsManager.saveToIndex(settings)) - .leftMap(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) - } - private def loadRorSettingFromIndex() = { - EitherT(settingsManager.loadFromIndex()) + EitherT(settingsSource.load()) .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) } + private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { + EitherT(settingsSource.save(settings)) + .leftMap(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) + } + } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index dd0354c994..04908ff384 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -30,10 +30,11 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration -import tech.beshu.ror.configuration.manager.RorTestSettingsManager import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value @@ -41,7 +42,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest esConfig: EsConfigBasedRorSettings, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], - testSettingsManager: RorTestSettingsManager) + testSettingsSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine("test", boot, esConfig, initialEngine, reloadInProgress) { @@ -181,8 +182,8 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } private def saveSettingsInIndex[A](newSettings: TestRorSettings.Present, - onFailure: SavingIndexSettingsError => A): EitherT[Task, A, Unit] = { - EitherT(testSettingsManager.saveToIndex(newSettings)) + onFailure: SavingSettingsError => A): EitherT[Task, A, Unit] = { + EitherT(testSettingsSource.save(newSettings)) .leftMap(onFailure) } @@ -207,7 +208,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { - EitherT(testSettingsManager.loadFromIndex()) + EitherT(testSettingsSource.load()) .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) } @@ -235,7 +236,7 @@ object TestSettingsBasedReloadableEngine { esConfig: EsConfigBasedRorSettings, initialEngine: ReadonlyRest.TestEngine, reloadInProgress: Semaphore[Task], - testSettingsManager: RorTestSettingsManager) + testSettingsSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler): TestSettingsBasedReloadableEngine = { val engine = initialEngine match { @@ -246,7 +247,7 @@ object TestSettingsBasedReloadableEngine { case TestEngine.Invalidated(settings, expiration) => InitialEngine.Invalidated(settings, engineExpiration(expiration)) } - new TestSettingsBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, testSettingsManager) + new TestSettingsBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, testSettingsSource) } private def engineExpiration(expiration: TestEngine.Expiration) = EngineExpiration(expiration.ttl, expiration.validTo) diff --git a/core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala similarity index 86% rename from core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index 5153c2cc9f..51684711a0 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -14,15 +14,15 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings +package tech.beshu.ror.settings.source import better.files.File import cats.data.EitherT import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} import monix.eval.Task -import tech.beshu.ror.settings.FileSettingsSource.LoadingError.FileNotExist -import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) extends ReadOnlySettingsSource[SETTINGS] { diff --git a/core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala similarity index 73% rename from core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index 6204171989..c341dfc922 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -14,16 +14,18 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings +package tech.beshu.ror.settings.source import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError class IndexSettingsSource[SETTINGS : Encoder : Decoder](settingsIndex: RorSettingsIndex) extends ReadWriteSettingsSource[SETTINGS] { - override def save(config: SETTINGS): Task[Either[ReadWriteSettingsSource.SavingSettingsError, Unit]] = ??? + override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = ??? - override def load(): Task[Either[ReadOnlySettingsSource.LoadingSettingsError, SETTINGS]] = ??? + override def save(config: SETTINGS): Task[Either[SavingSettingsError, Unit]] = ??? } diff --git a/core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala similarity index 73% rename from core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 58b67dc392..3ee1855749 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -14,12 +14,13 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings +package tech.beshu.ror.settings.source +import cats.Show import io.circe.{Decoder, Encoder} import monix.eval.Task -import tech.beshu.ror.settings.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError sealed trait SettingsSource[SETTINGS] @@ -30,8 +31,10 @@ object ReadOnlySettingsSource { sealed trait LoadingSettingsError object LoadingSettingsError { case object FormatError extends LoadingSettingsError - final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError +// final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError } + + implicit val show: Show[LoadingSettingsError] = ??? } trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder] extends ReadOnlySettingsSource[SETTINGS] { @@ -40,6 +43,8 @@ trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder] extends ReadOnlySett object ReadWriteSettingsSource { sealed trait SavingSettingsError object SavingSettingsError { - final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError +// final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError } + + implicit val show: Show[SavingSettingsError] = ??? } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala new file mode 100644 index 0000000000..355ad22cd8 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala @@ -0,0 +1,28 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.settings.source.FileSettingsSource +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError + +class RorMainSettingsFileOnlyLoadingStrategy(fileSettingsSource: FileSettingsSource[RawRorSettings]) + extends SettingsLoadingStrategy[LoadingSettingsError, RawRorSettings] { + + override def load(): Task[Either[LoadingSettingsError, RawRorSettings]] = ??? +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala new file mode 100644 index 0000000000..fbee445a43 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala @@ -0,0 +1,38 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError + +class RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource: IndexSettingsSource[RawRorSettings], + fileSettingsSource: FileSettingsSource[RawRorSettings], + /* todo: retry strategy*/) + extends SettingsLoadingStrategy[LoadingError, RawRorSettings] { + + override def load(): Task[Either[LoadingError, RawRorSettings]] = ??? + +} +object RorMainSettingsIndexWithFileFallbackLoadingStrategy { + + type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala new file mode 100644 index 0000000000..f630b6d9ea --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala @@ -0,0 +1,28 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task +import tech.beshu.ror.configuration.TestRorSettings +import tech.beshu.ror.settings.source.IndexSettingsSource +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError + +class RorTestSettingsIndexOnlyLoadingStrategy(indexSettingsSource: IndexSettingsSource[TestRorSettings]) + extends SettingsLoadingStrategy[LoadingSettingsError, TestRorSettings] { + + override def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = ??? +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala new file mode 100644 index 0000000000..47198f5c82 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala @@ -0,0 +1,24 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task + +// todo: do we need it? +trait SettingsLoadingStrategy[ERROR, SETTINGS] { + def load(): Task[Either[ERROR, SETTINGS]] +} From ded392018fcb551804bcb120d55fc0204d3ceafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 2 Sep 2025 08:30:49 +0200 Subject: [PATCH 025/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 21 +++++++++++-------- .../tech/beshu/ror/boot/RorInstance.scala | 16 +++++++------- .../settings/source/FileSettingsSource.scala | 5 ++--- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index adf4441823..b36318e618 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -35,10 +35,13 @@ import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.manager.* +import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, RorTestSettingsIndexOnlyLoadingStrategy} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -60,7 +63,7 @@ class ReadonlyRest(coreFactory: CoreFactory, rorTestSettingsLoader <- lift(new RorTestSettingsIndexOnlyLoadingStrategy(???)) loadedMainRorSettings <- loadMainSettings(rorMainSettingsLoader) loadedTestRorSettings <- loadTestSettings(esConfig, rorTestSettingsLoader) - instance <- startRor(esConfig, loadedMainRorSettings, rorMainSettingsLoader, loadedTestRorSettings, rorTestSettingsLoader) + instance <- startRor(esConfig, loadedMainRorSettings, ???, loadedTestRorSettings, ???) } yield instance).value } @@ -99,8 +102,8 @@ class ReadonlyRest(coreFactory: CoreFactory, error match { case Left(LoadingFromFileError.FileParsingError(message)) => StartingFailure(message) - case Left(LoadingFromFileError.FileNotExist(path)) => - StartingFailure(s"Cannot find settings file: ${path.show}") + case Left(LoadingFromFileError.FileNotExist(file)) => + StartingFailure(s"Cannot find settings file: ${file.show}") case Right(LoadingFromIndexError.IndexParsingError(message)) => StartingFailure(message) case Right(LoadingFromIndexError.IndexUnknownStructure) => @@ -112,13 +115,13 @@ class ReadonlyRest(coreFactory: CoreFactory, private def startRor(esConfig: EsConfigBasedRorSettings, loadedMainRorSettings: RawRorSettings, - mainSettingsManager: RorMainSettingsManager, + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], loadedTestRorSettings: TestRorSettings, - testSettingsManager: RorTestSettingsManager) = { + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) = { for { mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfig)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorSettings)) - rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsManager, testEngine, testSettingsManager, loadedMainRorSettings) + rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsIndexSource, testEngine, testSettingsIndexSource, loadedMainRorSettings) } yield rorInstance } @@ -166,12 +169,12 @@ class ReadonlyRest(coreFactory: CoreFactory, private def createRorInstance(esConfig: EsConfigBasedRorSettings, mainEngine: Engine, - mainSettingsManager: RorMainSettingsManager, + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], testEngine: TestEngine, - testSettingsManager: RorTestSettingsManager, + testSettingsIndexSource: IndexSettingsSource[TestRorSettings], alreadyLoadedSettings: RawRorSettings) = { EitherT.right[StartingFailure] { - RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsManager, testSettingsManager) + RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsIndexSource, testSettingsIndexSource) } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index b1ed099eab..6f82aa3e0c 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -217,15 +217,15 @@ object RorInstance { esConfig: EsConfigBasedRorSettings, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: IndexSettingsSource[RawRorSettings], - testSettingsManager: IndexSettingsSource[TestRorSettings]) + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - createInstance(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsManager, testSettingsManager) + createInstance(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsIndexSource, testSettingsIndexSource) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - createInstance(boot, esConfig, Mode.WithPeriodicIndexCheck(settings.refreshInterval), mainEngine, testEngine, mainSettingsManager, testSettingsManager) + createInstance(boot, esConfig, Mode.WithPeriodicIndexCheck(settings.refreshInterval), mainEngine, testEngine, mainSettingsIndexSource, testSettingsIndexSource) } } @@ -234,8 +234,8 @@ object RorInstance { mode: RorInstance.Mode, mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, - mainSettingsManager: IndexSettingsSource[RawRorSettings], - testSettingsManager: IndexSettingsSource[TestRorSettings]) + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { @@ -247,10 +247,10 @@ object RorInstance { mode = mode, mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, - mainSettingsIndexSource = mainSettingsManager, + mainSettingsIndexSource = mainSettingsIndexSource, testInitialEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, - testSettingsIndexSource = testSettingsManager + testSettingsIndexSource = testSettingsIndexSource, ) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index 51684711a0..380e04e19d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -20,9 +20,7 @@ import better.files.File import cats.data.EitherT import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} import monix.eval.Task -import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) extends ReadOnlySettingsSource[SETTINGS] { @@ -35,7 +33,8 @@ class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) } private def checkIfFileExist(file: File): EitherT[Task, LoadingSettingsError, File] = - EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) + ??? + // todo: EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) private def loadSettingsFromFile(file: File): EitherT[Task, LoadingSettingsError, SETTINGS] = { EitherT From 13f0d52127f95f3740a41d0248868615a289b8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 2 Sep 2025 13:56:26 +0200 Subject: [PATCH 026/103] wip --- .../BaseBasicAuthAuthenticationRule.scala | 2 +- .../beshu/ror/api/MainRorSettingsApi.scala | 5 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 91 ++++++++++--------- .../tech/beshu/ror/boot/RorInstance.scala | 19 ++-- .../MainSettingsBasedReloadableEngine.scala | 6 +- .../TestSettingsBasedReloadableEngine.scala | 5 +- .../settings/source/IndexSettingsSource.scala | 5 +- ...rMainSettingsFileOnlyLoadingStrategy.scala | 5 +- ...IndexWithFileFallbackLoadingStrategy.scala | 11 ++- ...TestSettingsIndexOnlyLoadingStrategy.scala | 5 +- 10 files changed, 87 insertions(+), 67 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/base/BaseBasicAuthAuthenticationRule.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/base/BaseBasicAuthAuthenticationRule.scala index 60da0a7bd1..f5328c0f55 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/base/BaseBasicAuthAuthenticationRule.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/auth/base/BaseBasicAuthAuthenticationRule.scala @@ -42,7 +42,7 @@ private [auth] abstract class BaseBasicAuthAuthenticationRule implicit val requestId: RequestId = requestContext.id.toRequestId requestContext.basicAuth.map(_.credentials) match { case Some(credentials) => - logger.debug(s"[${requestId.show}] Attempting Login as: ${credentials.user.show}") + logger.debug(s"[${requestId.show}] Attempting authenticate as: ${credentials.user.show}") authenticateUsing(credentials) .map { case true => Fulfilled(blockContext.withUserMetadata(_.withLoggedUser(DirectlyLoggedUser(credentials.user)))) diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index c8c66e400c..7cf5f83ad4 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.api -import cats.Show import cats.data.EitherT import cats.implicits.* import io.circe.Decoder @@ -60,9 +59,9 @@ class MainRorSettingsApi(rorInstance: RorInstance, rorInstance .forceReloadFromIndex() .map { - case Right(_) => + case Right(()) => ForceReloadMainSettings.Success("ReadonlyREST settings were reloaded with success!") - case Left(IndexSettingsReloadError.LoadingSettingsError(error)) => + case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => ForceReloadMainSettings.Failure(error.show) case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))) => ForceReloadMainSettings.Failure("Current settings are already loaded") diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index b36318e618..03f5967cf7 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -34,13 +34,10 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.manager.* -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, RorTestSettingsIndexOnlyLoadingStrategy} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -59,69 +56,78 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - rorMainSettingsLoader <- lift(new RorMainSettingsIndexWithFileFallbackLoadingStrategy(???, ???)) - rorTestSettingsLoader <- lift(new RorTestSettingsIndexOnlyLoadingStrategy(???)) - loadedMainRorSettings <- loadMainSettings(rorMainSettingsLoader) - loadedTestRorSettings <- loadTestSettings(esConfig, rorTestSettingsLoader) - instance <- startRor(esConfig, loadedMainRorSettings, ???, loadedTestRorSettings, ???) + // todo: refactor? + mainIndexSettingsSource <- lift { + indexContentService.toString + ??? : IndexSettingsSource[RawRorSettings] + } + mainFileSettingsSource <- lift(??? : FileSettingsSource[RawRorSettings]) + testIndexSettingsSource <- lift(??? : IndexSettingsSource[TestRorSettings]) + loadedMainRorSettings <- loadMainSettings(mainIndexSettingsSource, mainFileSettingsSource) + loadedTestRorSettings <- loadTestSettings(esConfig, testIndexSettingsSource) + instance <- startRor(esConfig, loadedMainRorSettings, mainIndexSettingsSource, mainFileSettingsSource, loadedTestRorSettings, testIndexSettingsSource) } yield instance).value } - private def loadMainSettings(rorSettingsLoader: RorMainSettingsIndexWithFileFallbackLoadingStrategy): EitherT[Task, StartingFailure, RawRorSettings] = { - EitherT(rorSettingsLoader.load()) + private def loadMainSettings(indexSettingsSource: IndexSettingsSource[RawRorSettings], + fileSettingsSource: FileSettingsSource[RawRorSettings]): EitherT[Task, StartingFailure, RawRorSettings] = { + val settingsLoader = new RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource, fileSettingsSource) + EitherT(settingsLoader.load()) .leftMap(toStartingFailure) } private def loadTestSettings(esConfig: EsConfigBasedRorSettings, - rorSettingsLoader: RorTestSettingsIndexOnlyLoadingStrategy): EitherT[Task, StartingFailure, TestRorSettings] = { + indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { esConfig.loadingRorCoreStrategy match { case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => - EitherT { - rorSettingsLoader.load() - }.leftFlatMap { - e => - e match { - case LoadingSettingsError.FormatError => ??? - } -// case LoadingFromIndexError.IndexParsingError(message) => -// logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") -// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) -// case LoadingFromIndexError.IndexUnknownStructure => -// logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") -// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) -// case LoadingFromIndexError.IndexNotExist => -// logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") -// EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - } + EitherT(new RorTestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) + .leftFlatMap { + case LoadingSettingsError.FormatError => ??? + // todo: + // case LoadingFromIndexError.IndexParsingError(message) => + // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") + // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + // case LoadingFromIndexError.IndexUnknownStructure => + // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") + // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + // case LoadingFromIndexError.IndexNotExist => + // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") + // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + } } } private def toStartingFailure(error: LoadingError) = { error match { - case Left(LoadingFromFileError.FileParsingError(message)) => - StartingFailure(message) - case Left(LoadingFromFileError.FileNotExist(file)) => - StartingFailure(s"Cannot find settings file: ${file.show}") - case Right(LoadingFromIndexError.IndexParsingError(message)) => - StartingFailure(message) - case Right(LoadingFromIndexError.IndexUnknownStructure) => - StartingFailure(s"Settings index is malformed") - case Right(LoadingFromIndexError.IndexNotExist) => - StartingFailure(s"Settings index doesn't exist") + case Left(LoadingSettingsError.FormatError) => + StartingFailure(???) + case Right(LoadingSettingsError.FormatError) => + StartingFailure(???) +// case Left(LoadingSettingsError.FileParsingError(message)) => +// StartingFailure(message) +// case Left(LoadingFromFileError.FileNotExist(file)) => +// StartingFailure(s"Cannot find settings file: ${file.show}") +// case Right(LoadingFromIndexError.IndexParsingError(message)) => +// StartingFailure(message) +// case Right(LoadingFromIndexError.IndexUnknownStructure) => +// StartingFailure(s"Settings index is malformed") +// case Right(LoadingFromIndexError.IndexNotExist) => +// StartingFailure(s"Settings index doesn't exist") } } private def startRor(esConfig: EsConfigBasedRorSettings, loadedMainRorSettings: RawRorSettings, mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], loadedTestRorSettings: TestRorSettings, testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) = { for { mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfig)) testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorSettings)) - rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsIndexSource, testEngine, testSettingsIndexSource, loadedMainRorSettings) + rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsIndexSource, mainSettingsFileSource, testEngine, testSettingsIndexSource, loadedMainRorSettings) } yield rorInstance } @@ -170,11 +176,12 @@ class ReadonlyRest(coreFactory: CoreFactory, private def createRorInstance(esConfig: EsConfigBasedRorSettings, mainEngine: Engine, mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], testEngine: TestEngine, testSettingsIndexSource: IndexSettingsSource[TestRorSettings], alreadyLoadedSettings: RawRorSettings) = { EitherT.right[StartingFailure] { - RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsIndexSource, testSettingsIndexSource) + RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) } } @@ -253,7 +260,7 @@ class ReadonlyRest(coreFactory: CoreFactory, StartingFailure(errorsMessage) } - private def notSetTestRorSettings: TestRorSettings = TestRorSettings.NotSet + //todo: private def notSetTestRorSettings: TestRorSettings = TestRorSettings.NotSet private def lift[A](value: => A) = { EitherT.liftF(Task.delay(value)) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 6f82aa3e0c..498adad891 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -34,6 +34,7 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrat import tech.beshu.ror.configuration.RorProperties.RefreshInterval import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -176,7 +177,7 @@ class RorInstance private(boot: ReadonlyRest, logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Stopping periodic ${name.show} settings check - application is being stopped") case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") - case (name, Left(EngineReloadError(IndexSettingsReloadError.LoadingSettingsError(error)))) => + case (name, Left(EngineReloadError(IndexSettingsReloadError.IndexLoadingSettingsError(error)))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") } @@ -218,15 +219,15 @@ object RorInstance { mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - esConfig.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => - createInstance(boot, esConfig, Mode.NoPeriodicIndexCheck, mainEngine, testEngine, mainSettingsIndexSource, testSettingsIndexSource) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => - createInstance(boot, esConfig, Mode.WithPeriodicIndexCheck(settings.refreshInterval), mainEngine, testEngine, mainSettingsIndexSource, testSettingsIndexSource) + val mode = esConfig.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => Mode.NoPeriodicIndexCheck + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => Mode.WithPeriodicIndexCheck(settings.refreshInterval) } + createInstance(boot, esConfig, mode, mainEngine, testEngine, mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) } private def createInstance(boot: ReadonlyRest, @@ -235,6 +236,7 @@ object RorInstance { mainEngine: ReadonlyRest.MainEngine, testEngine: ReadonlyRest.TestEngine, mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) = { @@ -248,9 +250,10 @@ object RorInstance { mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, mainSettingsIndexSource = mainSettingsIndexSource, + mainSettingsFileSource = mainSettingsFileSource, + testSettingsIndexSource = testSettingsIndexSource, testInitialEngine = testEngine, testReloadInProgress = isTestReloadInProgressSemaphore, - testSettingsIndexSource = testSettingsIndexSource, ) } @@ -269,7 +272,7 @@ object RorInstance { sealed trait IndexSettingsReloadError object IndexSettingsReloadError { - final case class LoadingSettingsError(underlying: LoadingSettingsError) extends IndexSettingsReloadError + final case class IndexLoadingSettingsError(underlying: LoadingSettingsError) extends IndexSettingsReloadError final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index a3138e24a5..257d9599a3 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -72,7 +72,7 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(_)) => // todo: SavingIndexSettingsError.CannotSaveSettings)) => // todo: invalidate created core? logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") }) @@ -95,7 +95,7 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(IndexSettingsReloadError.ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexSettingsReloadError.LoadingSettingsError(error)) => + case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${error.show}") }) } yield reloadResult.map(_ => ()) @@ -121,7 +121,7 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, private def loadRorSettingFromIndex() = { EitherT(settingsSource.load()) - .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) + .leftMap(IndexSettingsReloadError.IndexLoadingSettingsError.apply) } private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 04908ff384..bba9ab6dbb 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -30,7 +30,6 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.IndexSettingsSource @@ -104,7 +103,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}") case Left(ReloadError(RawSettingsReloadError.RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading tests settings skipped!") - case Left(IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(_)) => // todo: SavingIndexSettingsError.CannotSaveSettings)) => logger.error(s"[${requestId.show}] Saving ROR test settings in index failed") }) } yield reloadResult @@ -209,7 +208,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { EitherT(testSettingsSource.load()) - .leftMap(IndexSettingsReloadError.LoadingSettingsError.apply) + .leftMap(IndexSettingsReloadError.IndexLoadingSettingsError.apply) } private def invalidateTestSettingsByIndex[A]() diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index c341dfc922..2b5b4ab4cd 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -25,7 +25,10 @@ import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsErro class IndexSettingsSource[SETTINGS : Encoder : Decoder](settingsIndex: RorSettingsIndex) extends ReadWriteSettingsSource[SETTINGS] { - override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = ??? + override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = { + settingsIndex.toString + ??? + } override def save(config: SETTINGS): Task[Either[SavingSettingsError, Unit]] = ??? } diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala index 355ad22cd8..0994bf2cb1 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala @@ -24,5 +24,8 @@ import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsErro class RorMainSettingsFileOnlyLoadingStrategy(fileSettingsSource: FileSettingsSource[RawRorSettings]) extends SettingsLoadingStrategy[LoadingSettingsError, RawRorSettings] { - override def load(): Task[Either[LoadingSettingsError, RawRorSettings]] = ??? + override def load(): Task[Either[LoadingSettingsError, RawRorSettings]] = { + fileSettingsSource.toString + ??? + } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala index fbee445a43..45b3bda41b 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala @@ -18,8 +18,7 @@ package tech.beshu.ror.settings.strategy import monix.eval.Task import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.LoadingFromIndexError +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError @@ -28,11 +27,15 @@ class RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource: I /* todo: retry strategy*/) extends SettingsLoadingStrategy[LoadingError, RawRorSettings] { - override def load(): Task[Either[LoadingError, RawRorSettings]] = ??? + override def load(): Task[Either[LoadingError, RawRorSettings]] = { + indexSettingsSource.toString + fileSettingsSource.toString + ??? + } } object RorMainSettingsIndexWithFileFallbackLoadingStrategy { - type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] + type LoadingError = Either[LoadingSettingsError, LoadingSettingsError] } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala index f630b6d9ea..33ee0fadaa 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala @@ -24,5 +24,8 @@ import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsErro class RorTestSettingsIndexOnlyLoadingStrategy(indexSettingsSource: IndexSettingsSource[TestRorSettings]) extends SettingsLoadingStrategy[LoadingSettingsError, TestRorSettings] { - override def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = ??? + override def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = { + indexSettingsSource.toString + ??? + } } From 962a12f7dd4a4b548f9f48a631e9ebe47cee272d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 2 Sep 2025 14:20:21 +0200 Subject: [PATCH 027/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 4 +-- .../MainSettingsBasedReloadableEngine.scala | 4 +-- .../TestSettingsBasedReloadableEngine.scala | 4 +-- ...ndexWithFileFallbackLoadingStrategy.scala} | 5 ++- ...rMainSettingsFileOnlyLoadingStrategy.scala | 31 ------------------- .../strategy/SettingsLoadingStrategy.scala | 24 -------------- ...estSettingsIndexOnlyLoadingStrategy.scala} | 5 ++- 7 files changed, 10 insertions(+), 67 deletions(-) rename core/src/main/scala/tech/beshu/ror/settings/strategy/{RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala => MainSettingsIndexWithFileFallbackLoadingStrategy.scala} (91%) delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala rename core/src/main/scala/tech/beshu/ror/settings/strategy/{RorTestSettingsIndexOnlyLoadingStrategy.scala => TestSettingsIndexOnlyLoadingStrategy.scala} (79%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 03f5967cf7..02aef0e272 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -39,7 +39,7 @@ import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError -import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, RorTestSettingsIndexOnlyLoadingStrategy} +import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, TestSettingsIndexOnlyLoadingStrategy} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant @@ -82,7 +82,7 @@ class ReadonlyRest(coreFactory: CoreFactory, case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => - EitherT(new RorTestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) + EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) .leftFlatMap { case LoadingSettingsError.FormatError => ??? // todo: diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 257d9599a3..b143363eb0 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -101,8 +101,8 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, } yield reloadResult.map(_ => ()) } - def reloadEngineUsingIndexSettings() - (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { + private def reloadEngineUsingIndexSettings() + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { reloadInProgress.withPermit { reloadEngineUsingIndexSettingsWithoutPermit() } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index bba9ab6dbb..a4e7e929bc 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -190,7 +190,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, Unit]] = { value { for { - loadedSettings <- loadRorTestSettingsFromIndex() + loadedSettings <- loadTestSettings() result <- loadedSettings match { case TestRorSettings.NotSet => invalidateTestSettingsByIndex[IndexSettingsReloadError]() @@ -206,7 +206,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } } - private def loadRorTestSettingsFromIndex(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { + private def loadTestSettings(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { EitherT(testSettingsSource.load()) .leftMap(IndexSettingsReloadError.IndexLoadingSettingsError.apply) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala similarity index 91% rename from core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala rename to core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala index 45b3bda41b..e84bedeaa7 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsIndexWithFileFallbackLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala @@ -24,10 +24,9 @@ import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoad class RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource: IndexSettingsSource[RawRorSettings], fileSettingsSource: FileSettingsSource[RawRorSettings], - /* todo: retry strategy*/) - extends SettingsLoadingStrategy[LoadingError, RawRorSettings] { + /* todo: retry strategy*/) { - override def load(): Task[Either[LoadingError, RawRorSettings]] = { + def load(): Task[Either[LoadingError, RawRorSettings]] = { indexSettingsSource.toString fileSettingsSource.toString ??? diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala deleted file mode 100644 index 0994bf2cb1..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorMainSettingsFileOnlyLoadingStrategy.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.strategy - -import monix.eval.Task -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.settings.source.FileSettingsSource -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError - -class RorMainSettingsFileOnlyLoadingStrategy(fileSettingsSource: FileSettingsSource[RawRorSettings]) - extends SettingsLoadingStrategy[LoadingSettingsError, RawRorSettings] { - - override def load(): Task[Either[LoadingSettingsError, RawRorSettings]] = { - fileSettingsSource.toString - ??? - } -} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala deleted file mode 100644 index 47198f5c82..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/SettingsLoadingStrategy.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.strategy - -import monix.eval.Task - -// todo: do we need it? -trait SettingsLoadingStrategy[ERROR, SETTINGS] { - def load(): Task[Either[ERROR, SETTINGS]] -} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala similarity index 79% rename from core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala rename to core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala index 33ee0fadaa..5e76149725 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RorTestSettingsIndexOnlyLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala @@ -21,10 +21,9 @@ import tech.beshu.ror.configuration.TestRorSettings import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -class RorTestSettingsIndexOnlyLoadingStrategy(indexSettingsSource: IndexSettingsSource[TestRorSettings]) - extends SettingsLoadingStrategy[LoadingSettingsError, TestRorSettings] { +class TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource: IndexSettingsSource[TestRorSettings]) { - override def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = { + def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = { indexSettingsSource.toString ??? } From a80805c3d51f7b076248574dd39593f0f8934fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 2 Sep 2025 14:59:19 +0200 Subject: [PATCH 028/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 59 +--- .../loader/FileRorSettingsLoader.scala | 90 ++--- .../loader/RorSettingsLoader.scala | 2 +- .../manager/FileSettingsManager.scala | 36 +- .../manager/InIndexSettingsManager.scala | 50 +-- .../manager/RorMainSettingsManager.scala | 330 +++++++++--------- .../manager/RorTestSettingsManager.scala | 154 ++++---- .../main/scala/tech/beshu/ror/implicits.scala | 32 +- ...IndexWithFileFallbackLoadingStrategy.scala | 40 --- .../StartingRorSettingsLoadingStrategy.scala | 84 +++++ ...TestSettingsIndexOnlyLoadingStrategy.scala | 30 -- 11 files changed, 442 insertions(+), 465 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 02aef0e272..713beedfe9 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -33,13 +33,10 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} -import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError -import tech.beshu.ror.settings.strategy.{RorMainSettingsIndexWithFileFallbackLoadingStrategy, TestSettingsIndexOnlyLoadingStrategy} +import tech.beshu.ror.settings.strategy.StartingRorSettingsLoadingStrategy import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant @@ -63,59 +60,17 @@ class ReadonlyRest(coreFactory: CoreFactory, } mainFileSettingsSource <- lift(??? : FileSettingsSource[RawRorSettings]) testIndexSettingsSource <- lift(??? : IndexSettingsSource[TestRorSettings]) - loadedMainRorSettings <- loadMainSettings(mainIndexSettingsSource, mainFileSettingsSource) - loadedTestRorSettings <- loadTestSettings(esConfig, testIndexSettingsSource) + loadedSettings <- loadStartupSettings(mainIndexSettingsSource, mainFileSettingsSource, testIndexSettingsSource) + (loadedMainRorSettings, loadedTestRorSettings) = loadedSettings instance <- startRor(esConfig, loadedMainRorSettings, mainIndexSettingsSource, mainFileSettingsSource, loadedTestRorSettings, testIndexSettingsSource) } yield instance).value } - private def loadMainSettings(indexSettingsSource: IndexSettingsSource[RawRorSettings], - fileSettingsSource: FileSettingsSource[RawRorSettings]): EitherT[Task, StartingFailure, RawRorSettings] = { - val settingsLoader = new RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource, fileSettingsSource) + private def loadStartupSettings(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, (RawRorSettings, TestRorSettings)] = { + val settingsLoader = new StartingRorSettingsLoadingStrategy(mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) EitherT(settingsLoader.load()) - .leftMap(toStartingFailure) - } - - private def loadTestSettings(esConfig: EsConfigBasedRorSettings, - indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { - esConfig.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => - EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) - .leftFlatMap { - case LoadingSettingsError.FormatError => ??? - // todo: - // case LoadingFromIndexError.IndexParsingError(message) => - // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - // case LoadingFromIndexError.IndexUnknownStructure => - // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - // case LoadingFromIndexError.IndexNotExist => - // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - } - } - } - - private def toStartingFailure(error: LoadingError) = { - error match { - case Left(LoadingSettingsError.FormatError) => - StartingFailure(???) - case Right(LoadingSettingsError.FormatError) => - StartingFailure(???) -// case Left(LoadingSettingsError.FileParsingError(message)) => -// StartingFailure(message) -// case Left(LoadingFromFileError.FileNotExist(file)) => -// StartingFailure(s"Cannot find settings file: ${file.show}") -// case Right(LoadingFromIndexError.IndexParsingError(message)) => -// StartingFailure(message) -// case Right(LoadingFromIndexError.IndexUnknownStructure) => -// StartingFailure(s"Settings index is malformed") -// case Right(LoadingFromIndexError.IndexNotExist) => -// StartingFailure(s"Settings index doesn't exist") - } } private def startRor(esConfig: EsConfigBasedRorSettings, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala index ae0cf727ce..4b333f6e26 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala @@ -14,47 +14,49 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.loader - -import better.files.File -import cats.Show -import cats.data.EitherT -import monix.eval.Task -import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} - -class FileRorSettingsLoader(rorSettingsFile: File, - rawRorSettingsYamlParser: RawRorSettingsYamlParser) - extends RorSettingsLoader[FileRorSettingsLoader.Error] { - - def settingsFile: File = rorSettingsFile - - override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { - val file = rorSettingsFile - (for { - _ <- checkIfFileExist(file) - settings <- loadSettingsFromFile(file) - } yield settings).value - } - - private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], File] = - EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) - - private def loadSettingsFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { - EitherT(rawRorSettingsYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) - } -} - -object FileRorSettingsLoader { - - sealed trait Error - object Error { - final case class FileNotExist(file: File) extends Error - - implicit val show: Show[Error] = Show.show { - case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" - } - } -} \ No newline at end of file +//package tech.beshu.ror.configuration.loader +// +//import better.files.File +//import cats.Show +//import cats.data.EitherT +//import monix.eval.Task +//import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +//import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +// +//class FileRorSettingsLoader(rorSettingsFile: File, +// rawRorSettingsYamlParser: RawRorSettingsYamlParser) +// extends RorSettingsLoader[FileRorSettingsLoader.Error] { +// +// def settingsFile: File = rorSettingsFile +// +// override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { +// val file = rorSettingsFile +// (for { +// _ <- checkIfFileExist(file) +// settings <- loadSettingsFromFile(file) +// } yield settings).value +// } +// +// private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], File] = +// EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) +// +// private def loadSettingsFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { +// EitherT(rawRorSettingsYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) +// } +//} +// +//object FileRorSettingsLoader { +// +// sealed trait Error +// object Error { +// final case class FileNotExist(file: File) extends Error +// +// implicit val show: Show[Error] = Show.show { +// case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" +// } +// } +//} + +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala index 1ad23551da..ca4db9961c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala @@ -41,4 +41,4 @@ object RorSettingsLoader { } } -} \ No newline at end of file +} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala index 3a0672b27a..cf6315fda6 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala @@ -14,21 +14,23 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.manager +//package tech.beshu.ror.configuration.manager +// +//import better.files.File +//import monix.eval.Task +//import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +// +//trait FileSettingsManager[SETTINGS] { +// +// def loadFromFile(): Task[Either[LoadingFromFileError, SETTINGS]] +//} +//object FileSettingsManager { +// +// sealed trait LoadingFromFileError +// object LoadingFromFileError { +// final case class FileParsingError(message: String) extends LoadingFromFileError +// final case class FileNotExist(file: File) extends LoadingFromFileError +// } +//} -import better.files.File -import monix.eval.Task -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError - -trait FileSettingsManager[SETTINGS] { - - def loadFromFile(): Task[Either[LoadingFromFileError, SETTINGS]] -} -object FileSettingsManager { - - sealed trait LoadingFromFileError - object LoadingFromFileError { - final case class FileParsingError(message: String) extends LoadingFromFileError - final case class FileNotExist(file: File) extends LoadingFromFileError - } -} \ No newline at end of file +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala index 2288f64b90..279811e239 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala @@ -14,28 +14,30 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.manager +//package tech.beshu.ror.configuration.manager +// +//import monix.eval.Task +//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +// +//trait InIndexSettingsManager[SETTINGS] { +// +// def loadFromIndex(): Task[Either[LoadingFromIndexError, SETTINGS]] +// +// def saveToIndex(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] +//} +//object InIndexSettingsManager { +// +// sealed trait LoadingFromIndexError +// object LoadingFromIndexError { +// final case class IndexParsingError(message: String) extends LoadingFromIndexError +// case object IndexUnknownStructure extends LoadingFromIndexError +// case object IndexNotExist extends LoadingFromIndexError +// } +// +// sealed trait SavingIndexSettingsError +// object SavingIndexSettingsError { +// case object CannotSaveSettings extends SavingIndexSettingsError +// } +//} -import monix.eval.Task -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} - -trait InIndexSettingsManager[SETTINGS] { - - def loadFromIndex(): Task[Either[LoadingFromIndexError, SETTINGS]] - - def saveToIndex(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] -} -object InIndexSettingsManager { - - sealed trait LoadingFromIndexError - object LoadingFromIndexError { - final case class IndexParsingError(message: String) extends LoadingFromIndexError - case object IndexUnknownStructure extends LoadingFromIndexError - case object IndexNotExist extends LoadingFromIndexError - } - - sealed trait SavingIndexSettingsError - object SavingIndexSettingsError { - case object CannotSaveSettings extends SavingIndexSettingsError - } -} \ No newline at end of file +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala index b6a07181be..a9d005dc54 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala @@ -14,167 +14,169 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.manager - -import cats.data.EitherT -import cats.implicits.toShow -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} -import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexMainSettingsManager, IndexSettingsManager} -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.LoggerOps - -import scala.concurrent.duration.FiniteDuration -import scala.language.postfixOps - -class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, - fileSettingsLoader: FileRorSettingsLoader, - indexSettingsManager: IndexSettingsManager[RawRorSettings]) - extends FileSettingsManager[RawRorSettings] - with InIndexSettingsManager[RawRorSettings] - with Logging { - - def loadAccordingToStrategy(): Task[Either[LoadingError, RawRorSettings]] = { - def loadFromFileWithLoadingError(): Task[Either[LoadingError, RawRorSettings]] = - loadFromFile().map(_.left.map(Left.apply)) - - esConfigBasedRorSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => - loadFromFileWithLoadingError() - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => - for { - _ <- wait(parameters.loadingDelay.value.value) - result <- attemptLoadingFromIndex( - loadingAttemptsInterval = parameters.loadingAttemptsInterval, - loadingAttemptsCount = parameters.loadingAttemptsCount, - fallback = loadFromFileWithLoadingError() - ) - } yield result - } - } - - override def loadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { - val result = for { - _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${fileSettingsLoader.settingsFile.show}")) - settings <- EitherT(fileSettingsLoader.load()) - .leftMap(convertFileError) - .leftSemiflatTap { error => - logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") - } - } yield settings - result.value - } - - override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { - loadRorSettingsFromIndex() - } - - override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - EitherT(indexSettingsManager.save(settings)) - .leftMap { - case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings - } - .value - } - - private def attemptLoadingFromIndex(loadingAttemptsInterval: LoadingAttemptsInterval, - loadingAttemptsCount: LoadingAttemptsCount, - fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { - loadingAttemptsCount.value.value match { - case 0 => - fallback.map(identity) - case attemptsCount => - loadRorSettingsFromIndex() - .flatMap { - case Left(LoadingFromIndexError.IndexNotExist) => - for { - _ <- wait(loadingAttemptsInterval.value.value) - result <- attemptLoadingFromIndex( - loadingAttemptsInterval = loadingAttemptsInterval, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(loadingAttemptsCount.value.value - 1), - fallback = fallback - ) - } yield result - case Left(LoadingFromIndexError.IndexUnknownStructure) => - Task.now(Left(Right(LoadingFromIndexError.IndexUnknownStructure))) - case Left(error@LoadingFromIndexError.IndexParsingError(_)) => - Task.now(Left(Right(error))) - case Right(value) => - Task.now(Right(value)) - } - } - } - - private def loadRorSettingsFromIndex() = { - val settingsIndex = indexSettingsManager.settingsIndex - val result = for { - _ <- lift(logger.info(s"Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...")) - settings <- EitherT(indexSettingsManager.load()) - .leftMap(convertIndexError) - .biSemiflatTap( - { - case LoadingFromIndexError.IndexParsingError(message) => - logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") - case LoadingFromIndexError.IndexUnknownStructure => - logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") - case LoadingFromIndexError.IndexNotExist => - logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") - }, - rorSettings => { - logger.dDebug(s"Loaded ReadonlyREST settings from index: ${rorSettings.raw.show}") - } - ) - } yield settings - result.value - } - - private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { - error match { - case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) - case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) - } - } - - private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]): LoadingFromIndexError = - error match { - case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) - case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist - case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure - } - - private def wait(duration: FiniteDuration) = { - Task.sleep(duration).map(Right.apply) - } - - private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) -} - -object RorMainSettingsManager { - - type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] - - def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, - indexJsonContentService: IndexJsonContentService): RorMainSettingsManager = { - val rorSettingsFile = esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsFile - val yamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) - new RorMainSettingsManager( - esConfigBasedRorSettings, - new FileRorSettingsLoader(rorSettingsFile, yamlParser), - new IndexJsonContentServiceBasedIndexMainSettingsManager( - esConfigBasedRorSettings.rorSettingsIndex, - yamlParser, - indexJsonContentService, - ) - ) - } - -} \ No newline at end of file +//package tech.beshu.ror.configuration.manager +// +//import cats.data.EitherT +//import cats.implicits.toShow +//import monix.eval.Task +//import org.apache.logging.log4j.scala.Logging +//import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy +//import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} +//import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexMainSettingsManager, IndexSettingsManager} +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +//import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} +//import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError +//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +//import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError +//import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} +//import tech.beshu.ror.es.IndexJsonContentService +//import tech.beshu.ror.implicits.* +//import tech.beshu.ror.utils.ScalaOps.LoggerOps +// +//import scala.concurrent.duration.FiniteDuration +//import scala.language.postfixOps +// +//class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, +// fileSettingsLoader: FileRorSettingsLoader, +// indexSettingsManager: IndexSettingsManager[RawRorSettings]) +// extends FileSettingsManager[RawRorSettings] +// with InIndexSettingsManager[RawRorSettings] +// with Logging { +// +// def loadAccordingToStrategy(): Task[Either[LoadingError, RawRorSettings]] = { +// def loadFromFileWithLoadingError(): Task[Either[LoadingError, RawRorSettings]] = +// loadFromFile().map(_.left.map(Left.apply)) +// +// esConfigBasedRorSettings.loadingRorCoreStrategy match { +// case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => +// loadFromFileWithLoadingError() +// case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => +// for { +// _ <- wait(parameters.loadingDelay.value.value) +// result <- attemptLoadingFromIndex( +// loadingAttemptsInterval = parameters.loadingAttemptsInterval, +// loadingAttemptsCount = parameters.loadingAttemptsCount, +// fallback = loadFromFileWithLoadingError() +// ) +// } yield result +// } +// } +// +// override def loadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { +// val result = for { +// _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${fileSettingsLoader.settingsFile.show}")) +// settings <- EitherT(fileSettingsLoader.load()) +// .leftMap(convertFileError) +// .leftSemiflatTap { error => +// logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") +// } +// } yield settings +// result.value +// } +// +// override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { +// loadRorSettingsFromIndex() +// } +// +// override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { +// EitherT(indexSettingsManager.save(settings)) +// .leftMap { +// case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +// } +// .value +// } +// +// private def attemptLoadingFromIndex(loadingAttemptsInterval: LoadingAttemptsInterval, +// loadingAttemptsCount: LoadingAttemptsCount, +// fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { +// loadingAttemptsCount.value.value match { +// case 0 => +// fallback.map(identity) +// case attemptsCount => +// loadRorSettingsFromIndex() +// .flatMap { +// case Left(LoadingFromIndexError.IndexNotExist) => +// for { +// _ <- wait(loadingAttemptsInterval.value.value) +// result <- attemptLoadingFromIndex( +// loadingAttemptsInterval = loadingAttemptsInterval, +// loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(loadingAttemptsCount.value.value - 1), +// fallback = fallback +// ) +// } yield result +// case Left(LoadingFromIndexError.IndexUnknownStructure) => +// Task.now(Left(Right(LoadingFromIndexError.IndexUnknownStructure))) +// case Left(error@LoadingFromIndexError.IndexParsingError(_)) => +// Task.now(Left(Right(error))) +// case Right(value) => +// Task.now(Right(value)) +// } +// } +// } +// +// private def loadRorSettingsFromIndex() = { +// val settingsIndex = indexSettingsManager.settingsIndex +// val result = for { +// _ <- lift(logger.info(s"Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...")) +// settings <- EitherT(indexSettingsManager.load()) +// .leftMap(convertIndexError) +// .biSemiflatTap( +// { +// case LoadingFromIndexError.IndexParsingError(message) => +// logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") +// case LoadingFromIndexError.IndexUnknownStructure => +// logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") +// case LoadingFromIndexError.IndexNotExist => +// logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") +// }, +// rorSettings => { +// logger.dDebug(s"Loaded ReadonlyREST settings from index: ${rorSettings.raw.show}") +// } +// ) +// } yield settings +// result.value +// } +// +// private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { +// error match { +// case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) +// case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) +// } +// } +// +// private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]): LoadingFromIndexError = +// error match { +// case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) +// case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist +// case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure +// } +// +// private def wait(duration: FiniteDuration) = { +// Task.sleep(duration).map(Right.apply) +// } +// +// private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) +//} +// +//object RorMainSettingsManager { +// +// type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] +// +// def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, +// indexJsonContentService: IndexJsonContentService): RorMainSettingsManager = { +// val rorSettingsFile = esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsFile +// val yamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) +// new RorMainSettingsManager( +// esConfigBasedRorSettings, +// new FileRorSettingsLoader(rorSettingsFile, yamlParser), +// new IndexJsonContentServiceBasedIndexMainSettingsManager( +// esConfigBasedRorSettings.rorSettingsIndex, +// yamlParser, +// indexJsonContentService, +// ) +// ) +// } +// +//} + +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala index 0ebce098b6..d03b4c750a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala @@ -14,80 +14,82 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.manager +//package tech.beshu.ror.configuration.manager +// +//import cats.data.EitherT +//import monix.eval.Task +//import org.apache.logging.log4j.scala.Logging +//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError +//import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexTestSettingsManager, IndexSettingsManager} +//import tech.beshu.ror.configuration.loader.RorSettingsLoader +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} +//import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser, TestRorSettings} +//import tech.beshu.ror.es.IndexJsonContentService +//import tech.beshu.ror.implicits.* +//import tech.beshu.ror.utils.ScalaOps.LoggerOps +// +//import scala.language.postfixOps +// +//class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[TestRorSettings]) +// extends InIndexSettingsManager[TestRorSettings] +// with Logging { +// +// override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { +// val settingsIndex = indexSettingsManager.settingsIndex +// val result = for { +// _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...")) +// settings <- EitherT(indexSettingsManager.load()) +// .leftMap(convertIndexError) +// .biSemiflatTap( +// { +// case LoadingFromIndexError.IndexParsingError(message) => +// logger.dError(s"Loading ReadonlyREST test settings from index failed: ${message.show}") +// case LoadingFromIndexError.IndexUnknownStructure => +// logger.dInfo("Loading ReadonlyREST test settings from index failed: index content malformed") +// case LoadingFromIndexError.IndexNotExist => +// logger.dInfo("Loading ReadonlyREST test settings from index failed: cannot find index") +// }, +// { +// case TestRorSettings.Present(rawConfig, _, _) => +// logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${rawConfig.raw.show}") +// case TestRorSettings.NotSet => +// logger.dDebug("There was no ReadonlyREST test settings in the index. Test settings engine will be not initialized.") +// } +// ) +// } yield settings +// result.value +// } +// +// override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { +// EitherT(indexSettingsManager.save(settings)) +// .leftMap { +// case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +// } +// .value +// } +// +// private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingFromIndexError = +// error match { +// case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) +// case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist +// case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure +// } +// +// private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) +//} +//object RorTestSettingsManager { +// +// def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, +// indexJsonContentService: IndexJsonContentService): RorTestSettingsManager = { +// new RorTestSettingsManager( +// new IndexJsonContentServiceBasedIndexTestSettingsManager( +// settingsIndex = esConfigBasedRorSettings.rorSettingsIndex, +// indexJsonContentService = indexJsonContentService, +// rorSettingsYamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) +// ) +// ) +// } +//} -import cats.data.EitherT -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexTestSettingsManager, IndexSettingsManager} -import tech.beshu.ror.configuration.loader.RorSettingsLoader -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser, TestRorSettings} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.LoggerOps - -import scala.language.postfixOps - -class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[TestRorSettings]) - extends InIndexSettingsManager[TestRorSettings] - with Logging { - - override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { - val settingsIndex = indexSettingsManager.settingsIndex - val result = for { - _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...")) - settings <- EitherT(indexSettingsManager.load()) - .leftMap(convertIndexError) - .biSemiflatTap( - { - case LoadingFromIndexError.IndexParsingError(message) => - logger.dError(s"Loading ReadonlyREST test settings from index failed: ${message.show}") - case LoadingFromIndexError.IndexUnknownStructure => - logger.dInfo("Loading ReadonlyREST test settings from index failed: index content malformed") - case LoadingFromIndexError.IndexNotExist => - logger.dInfo("Loading ReadonlyREST test settings from index failed: cannot find index") - }, - { - case TestRorSettings.Present(rawConfig, _, _) => - logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${rawConfig.raw.show}") - case TestRorSettings.NotSet => - logger.dDebug("There was no ReadonlyREST test settings in the index. Test settings engine will be not initialized.") - } - ) - } yield settings - result.value - } - - override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - EitherT(indexSettingsManager.save(settings)) - .leftMap { - case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings - } - .value - } - - private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingFromIndexError = - error match { - case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) - case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist - case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure - } - - private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) -} -object RorTestSettingsManager { - - def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, - indexJsonContentService: IndexJsonContentService): RorTestSettingsManager = { - new RorTestSettingsManager( - new IndexJsonContentServiceBasedIndexTestSettingsManager( - settingsIndex = esConfigBasedRorSettings.rorSettingsIndex, - indexJsonContentService = indexJsonContentService, - rorSettingsYamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) - ) - ) - } -} +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 7621778da9..4c58e700a8 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -58,8 +58,6 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError. import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError -import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.utils.ScalaOps.* @@ -403,19 +401,19 @@ trait LogsShowInstances case LoadingError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" case LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" } - - implicit val loadingFromIndexErrorShow: Show[LoadingFromIndexError] = Show.show { - case LoadingFromIndexError.IndexNotExist => "Cannot find ReadonlyREST settings index" - case LoadingFromIndexError.IndexUnknownStructure => "Unknown structure of ReadonlyREST index settings document" - case LoadingFromIndexError.IndexParsingError(message) => s"Cannot parse in-index ReadonlyREST settings. Cause: $message" - } - - implicit val loadingFromFileErrorShow: Show[LoadingFromFileError] = Show.show { - case LoadingFromFileError.FileParsingError(message) => s"Cannot parse file ReadonlyREST settings. Cause: $message" - case LoadingFromFileError.FileNotExist(file) => s"Cannot find ReadonlyREST settings file: ${file.pathAsString}" - } - - implicit val savingIndexSettingsErrorShow: Show[SavingIndexSettingsError] = Show.show { - case SavingIndexSettingsError.CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" - } +// todo: fixme +// implicit val loadingFromIndexErrorShow: Show[LoadingFromIndexError] = Show.show { +// case LoadingFromIndexError.IndexNotExist => "Cannot find ReadonlyREST settings index" +// case LoadingFromIndexError.IndexUnknownStructure => "Unknown structure of ReadonlyREST index settings document" +// case LoadingFromIndexError.IndexParsingError(message) => s"Cannot parse in-index ReadonlyREST settings. Cause: $message" +// } + +// implicit val loadingFromFileErrorShow: Show[LoadingFromFileError] = Show.show { +// case LoadingFromFileError.FileParsingError(message) => s"Cannot parse file ReadonlyREST settings. Cause: $message" +// case LoadingFromFileError.FileNotExist(file) => s"Cannot find ReadonlyREST settings file: ${file.pathAsString}" +// } +// +// implicit val savingIndexSettingsErrorShow: Show[SavingIndexSettingsError] = Show.show { +// case SavingIndexSettingsError.CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" +// } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala deleted file mode 100644 index e84bedeaa7..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/MainSettingsIndexWithFileFallbackLoadingStrategy.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.strategy - -import monix.eval.Task -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} -import tech.beshu.ror.settings.strategy.RorMainSettingsIndexWithFileFallbackLoadingStrategy.LoadingError - -class RorMainSettingsIndexWithFileFallbackLoadingStrategy(indexSettingsSource: IndexSettingsSource[RawRorSettings], - fileSettingsSource: FileSettingsSource[RawRorSettings], - /* todo: retry strategy*/) { - - def load(): Task[Either[LoadingError, RawRorSettings]] = { - indexSettingsSource.toString - fileSettingsSource.toString - ??? - } - -} -object RorMainSettingsIndexWithFileFallbackLoadingStrategy { - - type LoadingError = Either[LoadingSettingsError, LoadingSettingsError] - -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala new file mode 100644 index 0000000000..410dd8ac7f --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala @@ -0,0 +1,84 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure +import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} + +class StartingRorSettingsLoadingStrategy(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings], + testSettingsIndexSource: IndexSettingsSource[TestRorSettings], + /* todo: retry strategy*/) { + + def load(): Task[Either[StartingFailure, (RawRorSettings, TestRorSettings)]] = { + mainSettingsIndexSource.toString + mainSettingsFileSource.toString + testSettingsIndexSource.toString + ??? + } + +// private def toStartingFailure(error: LoadingError) = { +// error match { +// case Left(LoadingSettingsError.FormatError) => +// StartingFailure(???) +// case Right(LoadingSettingsError.FormatError) => +// StartingFailure(???) +// // case Left(LoadingSettingsError.FileParsingError(message)) => +// // StartingFailure(message) +// // case Left(LoadingFromFileError.FileNotExist(file)) => +// // StartingFailure(s"Cannot find settings file: ${file.show}") +// // case Right(LoadingFromIndexError.IndexParsingError(message)) => +// // StartingFailure(message) +// // case Right(LoadingFromIndexError.IndexUnknownStructure) => +// // StartingFailure(s"Settings index is malformed") +// // case Right(LoadingFromIndexError.IndexNotExist) => +// // StartingFailure(s"Settings index doesn't exist") +// } +// } +// +// private def loadTestSettings(esConfig: EsConfigBasedRorSettings, +// indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { +// esConfig.loadingRorCoreStrategy match { +// case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => +// EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) +// case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => +// EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) +// .leftFlatMap { +// case LoadingSettingsError.FormatError => ??? +// // todo: +// // case LoadingFromIndexError.IndexParsingError(message) => +// // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") +// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) +// // case LoadingFromIndexError.IndexUnknownStructure => +// // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") +// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) +// // case LoadingFromIndexError.IndexNotExist => +// // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") +// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) +// } +// } +// } + +} +object StartingRorSettingsLoadingStrategy { + + type LoadingError = Either[LoadingSettingsError, LoadingSettingsError] + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala deleted file mode 100644 index 5e76149725..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/TestSettingsIndexOnlyLoadingStrategy.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.strategy - -import monix.eval.Task -import tech.beshu.ror.configuration.TestRorSettings -import tech.beshu.ror.settings.source.IndexSettingsSource -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError - -class TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource: IndexSettingsSource[TestRorSettings]) { - - def load(): Task[Either[LoadingSettingsError, TestRorSettings]] = { - indexSettingsSource.toString - ??? - } -} From 86026b31a195f92d563fd8e11cc34b0bb5728643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Sep 2025 19:37:53 +0200 Subject: [PATCH 029/103] wip --- .../tech/beshu/ror/api/AuthMockApi.scala | 2 +- .../beshu/ror/api/MainRorSettingsApi.scala | 19 +- .../beshu/ror/api/TestRorSettingsApi.scala | 10 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 30 +- .../tech/beshu/ror/boot/RorInstance.scala | 10 +- .../MainSettingsBasedReloadableEngine.scala | 2 +- .../TestSettingsBasedReloadableEngine.scala | 31 +- .../RawRorSettingsYamlParser.scala | 17 +- .../ror/configuration/TestRorSettings.scala | 22 +- ...ServiceBasedIndexMainSettingsManager.scala | 122 ++--- ...ServiceBasedIndexTestSettingsManager.scala | 476 +++++++++--------- .../ror/es/IndexJsonContentService.scala | 5 +- .../settings/source/FileSettingsSource.scala | 15 +- .../settings/source/IndexSettingsSource.scala | 53 +- .../source/MainSettingsFileSource.scala | 29 ++ .../source/MainSettingsIndexSource.scala | 36 ++ .../ror/settings/source/SettingsSource.scala | 25 +- .../source/TestSettingsIndexSource.scala | 206 ++++++++ .../StartingRorSettingsLoadingStrategy.scala | 8 +- 19 files changed, 713 insertions(+), 405 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index 5a95554583..059ed56ae0 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -163,7 +163,7 @@ class AuthMockApi(rorInstance: RorInstance) case Left(IndexSettingsUpdateError.TestSettingsInvalidated) => Left(AuthMockResponse.UpdateAuthMock.Invalidated(testSettingsInvalidatedMessage)) case Left(IndexSettingsUpdateError.IndexSettingsSavingError(error)) => - Left(AuthMockResponse.UpdateAuthMock.Failed(s"Cannot save auth services mocks: ${error.show}")) + Left(AuthMockResponse.UpdateAuthMock.Failed(s"Cannot save auth services mocks: ")) // todo: ${error.show}")) } } diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala index 7cf5f83ad4..7b446d239b 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala @@ -29,7 +29,6 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps @@ -62,7 +61,8 @@ class MainRorSettingsApi(rorInstance: RorInstance, case Right(()) => ForceReloadMainSettings.Success("ReadonlyREST settings were reloaded with success!") case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => - ForceReloadMainSettings.Failure(error.show) + ??? + //ForceReloadMainSettings.Failure(error.show) case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))) => ForceReloadMainSettings.Failure("Current settings are already loaded") case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)) => @@ -88,7 +88,8 @@ class MainRorSettingsApi(rorInstance: RorInstance, .load() .map { case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) - case Left(error) => ProvideFileMainSettings.Failure(error.show) + case Left(error) => ??? + // ProvideFileMainSettings.Failure(error.show) } } @@ -101,7 +102,9 @@ class MainRorSettingsApi(rorInstance: RorInstance, // todo: ??? // case Left(error@LoadingFromIndexError.IndexNotExist) => // ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) - case Left(error) => ProvideIndexMainSettings.Failure(error.show) + case Left(error) => + ??? + //ProvideIndexMainSettings.Failure(error.show) } } @@ -110,10 +113,11 @@ class MainRorSettingsApi(rorInstance: RorInstance, .left.map(error => MainSettingsResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage.show}]")) } - private def rorMainSettingsFrom(settingsString: String): EitherT[Task, MainSettingsResponse, RawRorSettings] = EitherT { + private def rorMainSettingsFrom(settingsString: String): EitherT[Task, MainSettingsResponse, RawRorSettings] = { settingsYamlParser .fromString(settingsString) - .map(_.left.map(error => UpdateIndexMainSettings.Failure(error.show))) + .left.map(error => UpdateIndexMainSettings.Failure(error.show): MainSettingsResponse) + .toEitherT[Task] } private def forceReloadAndSaveNewSettings(settings: RawRorSettings) @@ -121,7 +125,8 @@ class MainRorSettingsApi(rorInstance: RorInstance, EitherT(rorInstance.forceReloadAndSave(settings)) .leftMap { case IndexSettingsSavingError(error) => - UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") + ??? + //UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => UpdateIndexMainSettings.Failure(s"Current settings are already loaded") case ReloadError(RawSettingsReloadError.RorInstanceStopped) => diff --git a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala index 7a38cccb7a..bd20b4f7db 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala @@ -29,7 +29,6 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, RawSettingsReloadError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* @@ -72,10 +71,11 @@ class TestRorSettingsApi(rorInstance: RorInstance, .left.map(error => TestSettingsResponse.Failure.BadRequest(s"JSON body malformed: [${error.getPrettyMessage}]")) } - private def rorTestSettingsFrom(settingsString: String): EitherT[Task, TestSettingsResponse, RawRorSettings] = EitherT { + private def rorTestSettingsFrom(settingsString: String): EitherT[Task, TestSettingsResponse, RawRorSettings] = { settingsYamlParser .fromString(settingsString) - .map(_.left.map(error => TestSettingsResponse.UpdateTestSettings.FailedResponse(error.show))) + .left.map(error => TestSettingsResponse.UpdateTestSettings.FailedResponse(error.show): TestSettingsResponse) + .toEitherT[Task] } private def invalidateTestSettings() @@ -86,7 +86,7 @@ class TestRorSettingsApi(rorInstance: RorInstance, case Right(()) => TestSettingsResponse.InvalidateTestSettings.SuccessResponse("ROR Test settings are invalidated") case Left(IndexSettingsInvalidationError.IndexSettingsSavingError(error)) => - TestSettingsResponse.InvalidateTestSettings.FailedResponse(s"Cannot invalidate test settings: ${error.show}") + TestSettingsResponse.InvalidateTestSettings.FailedResponse(s"Cannot invalidate test settings: ") // todo: ${error.show}") } } @@ -144,7 +144,7 @@ class TestRorSettingsApi(rorInstance: RorInstance, } .leftMap { case IndexSettingsSavingError(error) => - TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ${error.show}") + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ") // todo: ${error.show}") case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Current settings are already loaded") case ReloadError(RawSettingsReloadError.RorInstanceStopped) => diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 713beedfe9..2e38320ede 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -35,7 +35,7 @@ import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource, MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} import tech.beshu.ror.settings.strategy.StartingRorSettingsLoadingStrategy import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -53,13 +53,9 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - // todo: refactor? - mainIndexSettingsSource <- lift { - indexContentService.toString - ??? : IndexSettingsSource[RawRorSettings] - } - mainFileSettingsSource <- lift(??? : FileSettingsSource[RawRorSettings]) - testIndexSettingsSource <- lift(??? : IndexSettingsSource[TestRorSettings]) + mainIndexSettingsSource <- lift(new MainSettingsIndexSource(indexContentService, esConfig.rorSettingsIndex)) + mainFileSettingsSource <- lift(new MainSettingsFileSource(???)) + testIndexSettingsSource <- lift(TestSettingsIndexSource.create(indexContentService, esConfig.rorSettingsIndex, ???)) loadedSettings <- loadStartupSettings(mainIndexSettingsSource, mainFileSettingsSource, testIndexSettingsSource) (loadedMainRorSettings, loadedTestRorSettings) = loadedSettings instance <- startRor(esConfig, loadedMainRorSettings, mainIndexSettingsSource, mainFileSettingsSource, loadedTestRorSettings, testIndexSettingsSource) @@ -68,7 +64,7 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadStartupSettings(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], mainSettingsFileSource: FileSettingsSource[RawRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, (RawRorSettings, TestRorSettings)] = { + testSettingsIndexSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, (RawRorSettings, Option[TestRorSettings])] = { val settingsLoader = new StartingRorSettingsLoadingStrategy(mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) EitherT(settingsLoader.load()) } @@ -77,7 +73,7 @@ class ReadonlyRest(coreFactory: CoreFactory, loadedMainRorSettings: RawRorSettings, mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], mainSettingsFileSource: FileSettingsSource[RawRorSettings], - loadedTestRorSettings: TestRorSettings, + loadedTestRorSettings: Option[TestRorSettings], testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) = { for { mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfig)) @@ -87,18 +83,18 @@ class ReadonlyRest(coreFactory: CoreFactory, } private def loadTestEngine(esConfig: EsConfigBasedRorSettings, - loadedTestRorSettings: TestRorSettings) = { + loadedTestRorSettings: Option[TestRorSettings]) = { loadedTestRorSettings match { - case TestRorSettings.NotSet => + case None => Task.now(TestEngine.NotConfigured) - case settings: TestRorSettings.Present if !settings.isExpired(systemContext.clock) => + case Some(settings) if !settings.isExpired(systemContext.clock) => loadActiveTestEngine(esConfig, settings) - case settings: TestRorSettings.Present => + case Some(settings) => loadInvalidatedTestEngine(settings) } } - private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testSettings: TestRorSettings.Present) = { + private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testSettings: TestRorSettings) = { for { _ <- Task.delay(authServicesMocksProvider.update(testSettings.mocks)) testEngine <- loadRorEngine(testSettings.rawSettings, esConfig) @@ -116,7 +112,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } yield testEngine } - private def loadInvalidatedTestEngine(testSettings: TestRorSettings.Present) = { + private def loadInvalidatedTestEngine(testSettings: TestRorSettings) = { Task .delay(authServicesMocksProvider.update(testSettings.mocks)) .map { _ => @@ -124,7 +120,7 @@ class ReadonlyRest(coreFactory: CoreFactory, } } - private def expirationFrom(expiration: TestRorSettings.Present.Expiration): TestEngine.Expiration = { + private def expirationFrom(expiration: TestRorSettings.Expiration): TestEngine.Expiration = { TestEngine.Expiration(expiration.ttl, expiration.validTo) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 498adad891..6ccd16bcd7 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -178,7 +178,7 @@ class RorInstance private(boot: ReadonlyRest, case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") case (name, Left(EngineReloadError(IndexSettingsReloadError.IndexLoadingSettingsError(error)))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed:") // todo: ${error.show}") } private def tryMainEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { @@ -267,25 +267,25 @@ object RorInstance { sealed trait IndexSettingsReloadWithUpdateError object IndexSettingsReloadWithUpdateError { final case class ReloadError(undefined: RawSettingsReloadError) extends IndexSettingsReloadWithUpdateError - final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsReloadWithUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsReloadWithUpdateError } sealed trait IndexSettingsReloadError object IndexSettingsReloadError { - final case class IndexLoadingSettingsError(underlying: LoadingSettingsError) extends IndexSettingsReloadError + final case class IndexLoadingSettingsError(underlying: LoadingSettingsError[IndexSettingsSource.LoadingError]) extends IndexSettingsReloadError final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError } sealed trait IndexSettingsUpdateError object IndexSettingsUpdateError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsUpdateError case object TestSettingsNotSet extends IndexSettingsUpdateError case object TestSettingsInvalidated extends IndexSettingsUpdateError } sealed trait IndexSettingsInvalidationError object IndexSettingsInvalidationError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError) extends IndexSettingsInvalidationError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsInvalidationError } private sealed trait ScheduledReloadError diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index b143363eb0..d036d6b462 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -96,7 +96,7 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, case Left(IndexSettingsReloadError.ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => - logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${error.show}") + logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ") // ${error.show}") // todo: }) } yield reloadResult.map(_ => ()) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index a4e7e929bc..42a12df16f 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -29,10 +29,12 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.TestRorSettings.Present.Expiration +import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.IndexSettingsSource +import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value @@ -71,9 +73,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest value { for { engineExpiration <- reloadEngine(settings, ttl).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) - testRorSettings = TestRorSettings.Present( + testRorSettings = TestRorSettings( rawSettings = settings, - expiration = TestRorSettings.Present.Expiration( + expiration = TestRorSettings.Expiration( ttl = engineExpiration.expiration.ttl, validTo = engineExpiration.expiration.validTo ), @@ -116,7 +118,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest invalidated <- invalidate(keepPreviousSettings = true) result <- invalidated match { case Some(invalidatedEngine) => - val settings = TestRorSettings.Present( + val settings = TestRorSettings( rawSettings = invalidatedEngine.settings, expiration = Expiration( ttl = invalidatedEngine.expiration.ttl, @@ -144,9 +146,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest for { settings <- readCurrentTestSettingsForUpdate() _ <- updateMocksProvider(mocks) - testRorSettings = TestRorSettings.Present( + testRorSettings = TestRorSettings( rawSettings = settings.rawSettings, - expiration = TestRorSettings.Present.Expiration( + expiration = TestRorSettings.Expiration( ttl = settings.configuredTtl, validTo = settings.validTo ), @@ -180,8 +182,8 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest EitherT.right(Task.delay(boot.authServicesMocksProvider.update(mocks))) } - private def saveSettingsInIndex[A](newSettings: TestRorSettings.Present, - onFailure: SavingSettingsError => A): EitherT[Task, A, Unit] = { + private def saveSettingsInIndex[A](newSettings: TestRorSettings, + onFailure: SavingSettingsError[SavingError] => A): EitherT[Task, A, Unit] = { EitherT(testSettingsSource.save(newSettings)) .leftMap(onFailure) } @@ -192,9 +194,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest for { loadedSettings <- loadTestSettings() result <- loadedSettings match { - case TestRorSettings.NotSet => + case None => invalidateTestSettingsByIndex[IndexSettingsReloadError]() - case TestRorSettings.Present(rawSettings, mocks, expiration) => + case Some(TestRorSettings(rawSettings, mocks, expiration)) => for { _ <- reloadEngine(rawSettings, expiration.validTo, expiration.ttl) .leftMap(IndexSettingsReloadError.ReloadError.apply) @@ -206,9 +208,14 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } } - private def loadTestSettings(): EitherT[Task, IndexSettingsReloadError, TestRorSettings] = { + private def loadTestSettings(): EitherT[Task, IndexSettingsReloadError, Option[TestRorSettings]] = { EitherT(testSettingsSource.load()) - .leftMap(IndexSettingsReloadError.IndexLoadingSettingsError.apply) + .map(Some(_)) + .leftFlatMap { + // IndexSettingsReloadError.IndexLoadingSettingsError.apply // todo: + case LoadingSettingsError.FormatError => ??? + case LoadingSettingsError.SourceSpecificError(LoadingError.IndexNotFound) => ??? + } } private def invalidateTestSettingsByIndex[A]() diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala index 52f6d15572..be662e4844 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala @@ -17,34 +17,25 @@ package tech.beshu.ror.configuration import better.files.File -import cats.effect.Resource import cats.Show import io.circe.{Json, ParsingFailure} -import monix.eval.Task import squants.information.Information import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlParser -import java.io.StringReader - class RawRorSettingsYamlParser(maxSize: Information) { private val yamlParser: YamlParser = new YamlParser(Some(maxSize)) - def fromFile(file: File): Task[Either[ParsingRorSettingsError, RawRorSettings]] = { + def fromFile(file: File): Either[ParsingRorSettingsError, RawRorSettings] = { fromString(file.contentAsString) } - def fromString(content: String): Task[Either[ParsingRorSettingsError, RawRorSettings]] = { - val contentResource = Resource.make(Task(new StringReader(content))) { reader => Task(reader.close()) } - contentResource.use { reader => - Task { - handleParseResult(yamlParser.parse(reader)) - .map(RawRorSettings(_, content)) - } - } + def fromString(content: String): Either[ParsingRorSettingsError, RawRorSettings] = { + handleParseResult(yamlParser.parse(content)) + .map(RawRorSettings(_, content)) } private def handleParseResult(result: Either[ParsingFailure, Json]) = { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala index eda8c505f9..fa83b2059d 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala @@ -17,23 +17,19 @@ package tech.beshu.ror.configuration import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks +import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.{Clock, Instant} -sealed trait TestRorSettings -object TestRorSettings { - - case object NotSet extends TestRorSettings - final case class Present(rawSettings: RawRorSettings, - mocks: AuthServicesMocks, - expiration: Present.Expiration) extends TestRorSettings { - def isExpired(clock: Clock): Boolean = { - expiration.validTo.isBefore(clock.instant()) - } +final case class TestRorSettings(rawSettings: RawRorSettings, + mocks: AuthServicesMocks, + expiration: Expiration) { + def isExpired(clock: Clock): Boolean = { + expiration.validTo.isBefore(clock.instant()) } +} - object Present { - final case class Expiration(ttl: PositiveFiniteDuration, validTo: Instant) - } +object TestRorSettings { + final case class Expiration(ttl: PositiveFiniteDuration, validTo: Instant) } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala index 87db7a3770..bd4efa34d8 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala @@ -14,64 +14,64 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.index - -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexMainSettingsManager.Const -import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.* -import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} - -final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, - override val rorSettingsYamlParser: RawRorSettingsYamlParser, - indexJsonContentService: IndexJsonContentService) - extends IndexSettingsManager[RawRorSettings] - with Logging { - - override def load(): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { - indexJsonContentService - .sourceOf(settingsIndex.index, Const.id) - .flatMap { - case Right(source) => - source - .find(_._1 == Const.settingsKey) - .map { case (_, rorYamlString) => - rorSettingsYamlParser - .fromString(rorYamlString) - .map(_.left.map(ParsingError.apply)) - } - .getOrElse { - settingsLoaderError(UnknownStructureOfIndexDocument) - } - case Left(CannotReachContentSource) => - settingsLoaderError(IndexNotExist) - case Left(ContentNotFound) => - settingsLoaderError(IndexNotExist) - } - } - - override def save(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - indexJsonContentService - .saveContent( - settingsIndex.index, - Const.id, - Map(Const.settingsKey -> settings.raw) - ) - .map { - _.left.map { case CannotWriteToIndex => CannotSaveSettings } - } - } -} -object IndexJsonContentServiceBasedIndexMainSettingsManager { - private [IndexJsonContentServiceBasedIndexMainSettingsManager] object Const { - val id = "1" - val settingsKey = "settings" - } -} +//package tech.beshu.ror.configuration.index +// +//import monix.eval.Task +//import org.apache.logging.log4j.scala.Logging +//import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +//import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexMainSettingsManager.Const +//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +//import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.* +//import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError +//import tech.beshu.ror.es.IndexJsonContentService +//import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} +// +//final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, +// override val rorSettingsYamlParser: RawRorSettingsYamlParser, +// indexJsonContentService: IndexJsonContentService) +// extends IndexSettingsManager[RawRorSettings] +// with Logging { +// +// override def load(): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { +// indexJsonContentService +// .sourceOf(settingsIndex.index, Const.id) +// .flatMap { +// case Right(source) => +// source +// .find(_._1 == Const.settingsKey) +// .map { case (_, rorYamlString) => +// rorSettingsYamlParser +// .fromString(rorYamlString) +// .map(_.left.map(ParsingError.apply)) +// } +// .getOrElse { +// settingsLoaderError(UnknownStructureOfIndexDocument) +// } +// case Left(CannotReachContentSource) => +// settingsLoaderError(IndexNotExist) +// case Left(ContentNotFound) => +// settingsLoaderError(IndexNotExist) +// } +// } +// +// override def save(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { +// indexJsonContentService +// .saveContent( +// settingsIndex.index, +// Const.id, +// Map(Const.settingsKey -> settings.raw) +// ) +// .map { +// _.left.map { case CannotWriteToIndex => CannotSaveSettings } +// } +// } +//} +//object IndexJsonContentServiceBasedIndexMainSettingsManager { +// private [IndexJsonContentServiceBasedIndexMainSettingsManager] object Const { +// val id = "1" +// val settingsKey = "settings" +// } +//} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala index c013bab9c3..98d166da2f 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala @@ -14,241 +14,243 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.index +//package tech.beshu.ror.configuration.index +// +//import cats.data.EitherT +//import cats.implicits.* +//import eu.timepit.refined.types.string.NonEmptyString +//import io.circe.syntax.EncoderOps +//import io.circe.{Codec, Decoder, Encoder} +//import monix.eval.Task +//import org.apache.logging.log4j.scala.Logging +//import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService +//import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} +//import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks +//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthenticationServiceMock.ExternalAuthenticationUserMock +//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthorizationServiceMock.ExternalAuthorizationServiceUserMock +//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.LdapUserMock +//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} +//import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId +//import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} +//import tech.beshu.ror.configuration.TestRorSettings.Present +//import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexTestSettingsManager.Const +//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.{IndexNotExist, UnknownStructureOfIndexDocument} +//import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings +//import tech.beshu.ror.configuration.loader.RorSettingsLoader +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} +//import tech.beshu.ror.configuration.{RawRorSettingsYamlParser, TestRorSettings} +//import tech.beshu.ror.es.IndexJsonContentService +//import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} +//import tech.beshu.ror.syntax.* +//import tech.beshu.ror.utils.DurationOps.* +//import tech.beshu.ror.utils.json.KeyCodec +// +//import java.time.format.DateTimeFormatter +//import java.time.{Instant, ZoneOffset} +//import scala.concurrent.duration.Duration +//import scala.util.Try +// +//final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, +// override val rorSettingsYamlParser: RawRorSettingsYamlParser, +// indexJsonContentService: IndexJsonContentService) +// extends IndexSettingsManager[TestRorSettings] +// with Logging { +// +// type Error = RorSettingsLoader.Error[LoadingIndexSettingsError] +// +// override def load(): Task[Either[Error, TestRorSettings]] = { +// indexJsonContentService +// .sourceOf(settingsIndex.index, Const.id) +// .flatMap { +// case Right(source) => +// val properties = source.collect { case (key: String, value: String) => (key, value) } +// getSettings(properties).value +// case Left(CannotReachContentSource) => +// settingsLoaderError(IndexNotExist) +// case Left(ContentNotFound) => +// Task.now(Right(TestRorSettings.NotSet)) +// } +// } +// +// override def save(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { +// indexJsonContentService +// .saveContent(settingsIndex.index, Const.id, formatSettings(settings)) +// .map { +// _.left.map { case CannotWriteToIndex => CannotSaveSettings } +// } +// } +// +// private def getSettings(config: Map[String, String]): EitherT[Task, Error, TestRorSettings] = { +// if (config.isEmpty) { +// EitherT.right[Error](Task.now(TestRorSettings.NotSet)).widen[TestRorSettings] +// } else { +// for { +// expirationTimeString <- getConfigProperty(config, Const.properties.expirationTime) +// expirationTtlString <- getConfigProperty(config, Const.properties.expirationTtl) +// rawRorConfigString <- getConfigProperty(config, Const.properties.settings) +// authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) +// rawRorConfig <- EitherT { +// rorSettingsYamlParser +// .fromString(rawRorConfigString) +// .map(_.left.map(ParsingError.apply)) +// } +// expirationTime <- getInstant(expirationTimeString) +// expirationTtl <- getExpirationTtl(expirationTtlString) +// mocks <- getMocks(authMocksConfigString) +// } yield Present( +// rawSettings = rawRorConfig, +// mocks = mocks, +// expiration = Present.Expiration(ttl = expirationTtl, validTo = expirationTime) +// ) +// } +// } +// +// private def formatSettings(config: TestRorSettings): Map[String, String] = { +// config match { +// case TestRorSettings.NotSet => +// Map.empty +// case Present(rawConfig, mocks, expiration) => +// Map( +// Const.properties.expirationTime -> expiration.validTo.atOffset(ZoneOffset.UTC).toString, +// Const.properties.expirationTtl -> expiration.ttl.value.toMillis.toString, +// Const.properties.mocks -> formatMocks(mocks), +// Const.properties.settings -> rawConfig.raw +// ) +// } +// } +// +// private def getExpirationTtl(value: String): EitherT[Task, Error, PositiveFiniteDuration] = { +// Try { +// Duration +// .apply(value.toLong, "ms") +// .toRefinedPositive +// .leftMap((_: String) => parserError) +// } +// .toEither +// .leftMap(_ => parserError) +// .flatten +// .toEitherT[Task] +// } +// +// private def parserError: Error = +// SpecializedError[LoadingIndexSettingsError](UnknownStructureOfIndexDocument) +// +// private def getInstant(value: String): EitherT[Task, Error, Instant] = { +// Try(DateTimeFormatter.ISO_DATE_TIME.parse(value)) +// .map(Instant.from) +// .toEither +// .toEitherT[Task] +// .leftMap(_ => parserError) +// } +// +// private def formatMocks(mocks: AuthServicesMocks): String = { +// mocks.asJson.noSpaces +// } +// +// private def getMocks(config: String): EitherT[Task, Error, AuthServicesMocks] = { +// io.circe.parser.decode[AuthServicesMocks](config) +// .leftMap(_ => parserError) +// .toEitherT[Task] +// } +// +// private implicit val mocksCodec: Codec[AuthServicesMocks] = { +// implicit val nonEmptyStringCodec: Codec[NonEmptyString] = +// Codec.from(Decoder.decodeString.emap(NonEmptyString.from), Encoder.encodeString.contramap(_.value)) +// implicit val userIdCodec: Codec[User.Id] = +// Codec.from(nonEmptyStringCodec.map(User.Id.apply), nonEmptyStringCodec.contramap(_.value)) +// implicit val groupIdCodec: Codec[GroupId] = +// Codec.from( +// nonEmptyStringCodec.map(GroupId.apply), +// nonEmptyStringCodec.contramap(_.value) +// ) +// +// implicit val groupCodec: Codec[Group] = { +// implicit val groupNameCodec: Codec[GroupName] = Codec.from( +// nonEmptyStringCodec.map(GroupName.apply), +// nonEmptyStringCodec.contramap(_.value) +// ) +// Codec.forProduct2("id", "name")(Group.apply)(group => (group.id, group.name)) +// } +// implicit val ldapServiceMock: Codec[LdapServiceMock] = { +// implicit val userMock: Codec[LdapUserMock] = { +// // "groups" left for backward compatibility +// val encoder: Encoder[LdapUserMock] = Encoder.forProduct3("id", "groups", "userGroups")( +// userMock => (userMock.id, userMock.groups.map(_.id), userMock.groups) +// ) +// val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => +// LdapUserMock(id, groupIds.map(Group.from).toCovariantSet) +// ) +// val decoder: Decoder[LdapUserMock] = Decoder.forProduct2("id", "userGroups")(LdapUserMock.apply) +// Codec.from(decoder.or(deprecatedFormatDecoder), encoder) +// } +// Codec.forProduct1("users")(LdapServiceMock.apply)(_.users) +// } +// +// implicit val extAuthenticationMock: Codec[ExternalAuthenticationServiceMock] = { +// implicit val userMock: Codec[ExternalAuthenticationUserMock] = +// Codec.forProduct1("id")(ExternalAuthenticationUserMock.apply)(_.id) +// Codec.forProduct1("users")(ExternalAuthenticationServiceMock.apply)(_.users) +// } +// +// implicit val extAuthorizationMock: Codec[ExternalAuthorizationServiceMock] = { +// implicit val userMock: Codec[ExternalAuthorizationServiceUserMock] = { +// // "groups" left for backward compatibility +// val encoder = Encoder.forProduct3("id", "groups", "userGroups")( +// (userMock: ExternalAuthorizationServiceUserMock) => (userMock.id, userMock.groups.map(_.id), userMock.groups) +// ) +// val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => +// ExternalAuthorizationServiceUserMock(id, groupIds.map(Group.from).toCovariantSet) +// ) +// val decoder = Decoder.forProduct2("id", "userGroups")(ExternalAuthorizationServiceUserMock.apply) +// Codec.from(decoder.or(deprecatedFormatDecoder), encoder) +// } +// Codec.forProduct1("users")(ExternalAuthorizationServiceMock.apply)(_.users) +// } +// +// implicit val ldapKeyCodec: KeyCodec[LdapService.Name] = KeyCodec.from[LdapService.Name]( +// NonEmptyString.unapply(_).map(LdapService.Name.apply), +// _.value.value +// ) +// +// implicit val externalAuthenticationKeyCodec: KeyCodec[ExternalAuthenticationService.Name] = +// KeyCodec.from[ExternalAuthenticationService.Name]( +// NonEmptyString.unapply(_).map(ExternalAuthenticationService.Name.apply), +// _.value.value +// ) +// +// implicit val externalAuthorizationKeyCodec: KeyCodec[ExternalAuthorizationService.Name] = +// KeyCodec.from[ExternalAuthorizationService.Name]( +// NonEmptyString.unapply(_).map(ExternalAuthorizationService.Name.apply), +// _.value.value +// ) +// +// Codec.forProduct3( +// "ldapMocks", +// "externalAuthenticationMocks", +// "externalAuthorizationMocks" +// )(AuthServicesMocks.apply)(e => (e.ldapMocks, e.externalAuthenticationServiceMocks, e.externalAuthorizationServiceMocks)) +// } +// +// private def getConfigProperty[A, B](map: Map[A, B], key: A): EitherT[Task, Error, B] = { +// map +// .get(key) +// .toRight(parserError) +// .toEitherT[Task] +// } +// +//} +// +//private object IndexJsonContentServiceBasedIndexTestSettingsManager { +// private [IndexJsonContentServiceBasedIndexTestSettingsManager] object Const { +// val id = "2" +// object properties { +// val settings = "settings" +// val expirationTtl = "expiration_ttl_millis" +// val expirationTime = "expiration_timestamp" +// val mocks = "auth_services_mocks" +// } +// } +//} -import cats.data.EitherT -import cats.implicits.* -import eu.timepit.refined.types.string.NonEmptyString -import io.circe.syntax.EncoderOps -import io.circe.{Codec, Decoder, Encoder} -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService -import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} -import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks -import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthenticationServiceMock.ExternalAuthenticationUserMock -import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthorizationServiceMock.ExternalAuthorizationServiceUserMock -import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.LdapUserMock -import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} -import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId -import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} -import tech.beshu.ror.configuration.TestRorSettings.Present -import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexTestSettingsManager.Const -import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.{IndexNotExist, UnknownStructureOfIndexDocument} -import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -import tech.beshu.ror.configuration.loader.RorSettingsLoader -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -import tech.beshu.ror.configuration.{RawRorSettingsYamlParser, TestRorSettings} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -import tech.beshu.ror.syntax.* -import tech.beshu.ror.utils.DurationOps.* -import tech.beshu.ror.utils.json.KeyCodec - -import java.time.format.DateTimeFormatter -import java.time.{Instant, ZoneOffset} -import scala.concurrent.duration.Duration -import scala.util.Try - -final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, - override val rorSettingsYamlParser: RawRorSettingsYamlParser, - indexJsonContentService: IndexJsonContentService) - extends IndexSettingsManager[TestRorSettings] - with Logging { - - type Error = RorSettingsLoader.Error[LoadingIndexSettingsError] - - override def load(): Task[Either[Error, TestRorSettings]] = { - indexJsonContentService - .sourceOf(settingsIndex.index, Const.id) - .flatMap { - case Right(source) => - val properties = source.collect { case (key: String, value: String) => (key, value) } - getSettings(properties).value - case Left(CannotReachContentSource) => - settingsLoaderError(IndexNotExist) - case Left(ContentNotFound) => - Task.now(Right(TestRorSettings.NotSet)) - } - } - - override def save(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { - indexJsonContentService - .saveContent(settingsIndex.index, Const.id, formatSettings(settings)) - .map { - _.left.map { case CannotWriteToIndex => CannotSaveSettings } - } - } - - private def getSettings(config: Map[String, String]): EitherT[Task, Error, TestRorSettings] = { - if (config.isEmpty) { - EitherT.right[Error](Task.now(TestRorSettings.NotSet)).widen[TestRorSettings] - } else { - for { - expirationTimeString <- getConfigProperty(config, Const.properties.expirationTime) - expirationTtlString <- getConfigProperty(config, Const.properties.expirationTtl) - rawRorConfigString <- getConfigProperty(config, Const.properties.settings) - authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) - rawRorConfig <- EitherT { - rorSettingsYamlParser - .fromString(rawRorConfigString) - .map(_.left.map(ParsingError.apply)) - } - expirationTime <- getInstant(expirationTimeString) - expirationTtl <- getExpirationTtl(expirationTtlString) - mocks <- getMocks(authMocksConfigString) - } yield Present( - rawSettings = rawRorConfig, - mocks = mocks, - expiration = Present.Expiration(ttl = expirationTtl, validTo = expirationTime) - ) - } - } - - private def formatSettings(config: TestRorSettings): Map[String, String] = { - config match { - case TestRorSettings.NotSet => - Map.empty - case Present(rawConfig, mocks, expiration) => - Map( - Const.properties.expirationTime -> expiration.validTo.atOffset(ZoneOffset.UTC).toString, - Const.properties.expirationTtl -> expiration.ttl.value.toMillis.toString, - Const.properties.mocks -> formatMocks(mocks), - Const.properties.settings -> rawConfig.raw - ) - } - } - - private def getExpirationTtl(value: String): EitherT[Task, Error, PositiveFiniteDuration] = { - Try { - Duration - .apply(value.toLong, "ms") - .toRefinedPositive - .leftMap((_: String) => parserError) - } - .toEither - .leftMap(_ => parserError) - .flatten - .toEitherT[Task] - } - - private def parserError: Error = - SpecializedError[LoadingIndexSettingsError](UnknownStructureOfIndexDocument) - - private def getInstant(value: String): EitherT[Task, Error, Instant] = { - Try(DateTimeFormatter.ISO_DATE_TIME.parse(value)) - .map(Instant.from) - .toEither - .toEitherT[Task] - .leftMap(_ => parserError) - } - - private def formatMocks(mocks: AuthServicesMocks): String = { - mocks.asJson.noSpaces - } - - private def getMocks(config: String): EitherT[Task, Error, AuthServicesMocks] = { - io.circe.parser.decode[AuthServicesMocks](config) - .leftMap(_ => parserError) - .toEitherT[Task] - } - - private implicit val mocksCodec: Codec[AuthServicesMocks] = { - implicit val nonEmptyStringCodec: Codec[NonEmptyString] = - Codec.from(Decoder.decodeString.emap(NonEmptyString.from), Encoder.encodeString.contramap(_.value)) - implicit val userIdCodec: Codec[User.Id] = - Codec.from(nonEmptyStringCodec.map(User.Id.apply), nonEmptyStringCodec.contramap(_.value)) - implicit val groupIdCodec: Codec[GroupId] = - Codec.from( - nonEmptyStringCodec.map(GroupId.apply), - nonEmptyStringCodec.contramap(_.value) - ) - - implicit val groupCodec: Codec[Group] = { - implicit val groupNameCodec: Codec[GroupName] = Codec.from( - nonEmptyStringCodec.map(GroupName.apply), - nonEmptyStringCodec.contramap(_.value) - ) - Codec.forProduct2("id", "name")(Group.apply)(group => (group.id, group.name)) - } - implicit val ldapServiceMock: Codec[LdapServiceMock] = { - implicit val userMock: Codec[LdapUserMock] = { - // "groups" left for backward compatibility - val encoder: Encoder[LdapUserMock] = Encoder.forProduct3("id", "groups", "userGroups")( - userMock => (userMock.id, userMock.groups.map(_.id), userMock.groups) - ) - val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => - LdapUserMock(id, groupIds.map(Group.from).toCovariantSet) - ) - val decoder: Decoder[LdapUserMock] = Decoder.forProduct2("id", "userGroups")(LdapUserMock.apply) - Codec.from(decoder.or(deprecatedFormatDecoder), encoder) - } - Codec.forProduct1("users")(LdapServiceMock.apply)(_.users) - } - - implicit val extAuthenticationMock: Codec[ExternalAuthenticationServiceMock] = { - implicit val userMock: Codec[ExternalAuthenticationUserMock] = - Codec.forProduct1("id")(ExternalAuthenticationUserMock.apply)(_.id) - Codec.forProduct1("users")(ExternalAuthenticationServiceMock.apply)(_.users) - } - - implicit val extAuthorizationMock: Codec[ExternalAuthorizationServiceMock] = { - implicit val userMock: Codec[ExternalAuthorizationServiceUserMock] = { - // "groups" left for backward compatibility - val encoder = Encoder.forProduct3("id", "groups", "userGroups")( - (userMock: ExternalAuthorizationServiceUserMock) => (userMock.id, userMock.groups.map(_.id), userMock.groups) - ) - val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => - ExternalAuthorizationServiceUserMock(id, groupIds.map(Group.from).toCovariantSet) - ) - val decoder = Decoder.forProduct2("id", "userGroups")(ExternalAuthorizationServiceUserMock.apply) - Codec.from(decoder.or(deprecatedFormatDecoder), encoder) - } - Codec.forProduct1("users")(ExternalAuthorizationServiceMock.apply)(_.users) - } - - implicit val ldapKeyCodec: KeyCodec[LdapService.Name] = KeyCodec.from[LdapService.Name]( - NonEmptyString.unapply(_).map(LdapService.Name.apply), - _.value.value - ) - - implicit val externalAuthenticationKeyCodec: KeyCodec[ExternalAuthenticationService.Name] = - KeyCodec.from[ExternalAuthenticationService.Name]( - NonEmptyString.unapply(_).map(ExternalAuthenticationService.Name.apply), - _.value.value - ) - - implicit val externalAuthorizationKeyCodec: KeyCodec[ExternalAuthorizationService.Name] = - KeyCodec.from[ExternalAuthorizationService.Name]( - NonEmptyString.unapply(_).map(ExternalAuthorizationService.Name.apply), - _.value.value - ) - - Codec.forProduct3( - "ldapMocks", - "externalAuthenticationMocks", - "externalAuthorizationMocks" - )(AuthServicesMocks.apply)(e => (e.ldapMocks, e.externalAuthenticationServiceMocks, e.externalAuthorizationServiceMocks)) - } - - private def getConfigProperty[A, B](map: Map[A, B], key: A): EitherT[Task, Error, B] = { - map - .get(key) - .toRight(parserError) - .toEitherT[Task] - } - -} - -private object IndexJsonContentServiceBasedIndexTestSettingsManager { - private [IndexJsonContentServiceBasedIndexTestSettingsManager] object Const { - val id = "2" - object properties { - val settings = "settings" - val expirationTtl = "expiration_ttl_millis" - val expirationTime = "expiration_timestamp" - val mocks = "auth_services_mocks" - } - } -} \ No newline at end of file +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala b/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala index 77dcdcaec7..332123813c 100644 --- a/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala +++ b/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala @@ -16,14 +16,17 @@ */ package tech.beshu.ror.es +import io.circe.Json import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.es.IndexJsonContentService.{ReadError, WriteError} trait IndexJsonContentService { - + // todo: def sourceOf(index: IndexName.Full, id: String): Task[Either[ReadError, Map[String, String]]] + def sourceOfAsString(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = ??? def saveContent(index: IndexName.Full, id: String, content: Map[String, String]): Task[Either[WriteError, Unit]] + def saveContentJson(index: IndexName.Full, id: String, content: Json): Task[Either[WriteError, Unit]] = ??? } object IndexJsonContentService { diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index 380e04e19d..6395ad0e8c 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -20,25 +20,26 @@ import better.files.File import cats.data.EitherT import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} import monix.eval.Task +import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) - extends ReadOnlySettingsSource[SETTINGS] { + extends ReadOnlySettingsSource[SETTINGS, FileSettingsSource.LoadingError] { - override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = { + override def load(): Task[Either[LoadingSettingsError[FileSettingsSource.LoadingError], SETTINGS]] = { (for { _ <- checkIfFileExist(rorSettingsFile) settings <- loadSettingsFromFile(rorSettingsFile) } yield settings).value } - private def checkIfFileExist(file: File): EitherT[Task, LoadingSettingsError, File] = - ??? - // todo: EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) + private def checkIfFileExist(file: File): EitherT[Task, LoadingSettingsError[FileSettingsSource.LoadingError], File] = + EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) - private def loadSettingsFromFile(file: File): EitherT[Task, LoadingSettingsError, SETTINGS] = { + private def loadSettingsFromFile(file: File): EitherT[Task, LoadingSettingsError[FileSettingsSource.LoadingError], SETTINGS] = { EitherT - .pure[Task, LoadingSettingsError](file.contentAsString) + .pure[Task, LoadingSettingsError[FileSettingsSource.LoadingError]](file.contentAsString) .subflatMap { raw => parser .decode(raw) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index 2b5b4ab4cd..3ad94f5f40 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -16,19 +16,60 @@ */ package tech.beshu.ror.settings.source +import io.circe.syntax.* import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +import tech.beshu.ror.es.IndexJsonContentService +import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} +import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.IndexNotFound +import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError -class IndexSettingsSource[SETTINGS : Encoder : Decoder](settingsIndex: RorSettingsIndex) - extends ReadWriteSettingsSource[SETTINGS] { +class IndexSettingsSource[SETTINGS : Encoder : Decoder](indexJsonContentService: IndexJsonContentService, + settingsIndex: RorSettingsIndex, + documentId: String) + extends ReadWriteSettingsSource[SETTINGS, LoadingError, SavingError] { - override def load(): Task[Either[LoadingSettingsError, SETTINGS]] = { - settingsIndex.toString - ??? + override def load(): Task[Either[LoadingSettingsError[LoadingError], SETTINGS]] = { + indexJsonContentService + .sourceOfAsString(settingsIndex.index, documentId) + .map { + case Right(document) => + document + .as[SETTINGS] + .left.flatMap { _ => + settingsLoaderError(IndexNotFound) // todo: wrong type + } + case Left(CannotReachContentSource) => + settingsLoaderError(IndexNotFound) + case Left(ContentNotFound) => + settingsLoaderError(IndexNotFound) + } } - override def save(config: SETTINGS): Task[Either[SavingSettingsError, Unit]] = ??? + override def save(settings: SETTINGS): Task[Either[SavingSettingsError[SavingError], Unit]] = { + indexJsonContentService + .saveContentJson(settingsIndex.index, documentId, settings.asJson) + .map { + _.left.map { case CannotWriteToIndex => SavingSettingsError.SourceSpecificError(CannotSaveSettings) } + } + } + + private def settingsLoaderError(error: LoadingError) = + Left(LoadingSettingsError.SourceSpecificError(error)) + +} +object IndexSettingsSource { + sealed trait LoadingError + object LoadingError { + case object IndexNotFound extends LoadingError + } + + sealed trait SavingError + object SavingError { + case object CannotSaveSettings extends SavingError + } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala new file mode 100644 index 0000000000..a2aac9d727 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala @@ -0,0 +1,29 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.source + +import io.circe.Decoder +import tech.beshu.ror.configuration.RawRorSettings +import MainSettingsFileSource.decoder +import better.files.File + +class MainSettingsFileSource(rorSettingsFile: File) + extends FileSettingsSource[RawRorSettings](rorSettingsFile) + +object MainSettingsFileSource { + implicit val decoder: Decoder[RawRorSettings] = ??? +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala new file mode 100644 index 0000000000..2141c75ca3 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala @@ -0,0 +1,36 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.source + +import io.circe.Codec +import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.es.IndexJsonContentService +import tech.beshu.ror.settings.source.MainSettingsIndexSource.{Const, codec} + +class MainSettingsIndexSource(indexJsonContentService: IndexJsonContentService, + settingsIndex: RorSettingsIndex) + extends IndexSettingsSource[RawRorSettings](indexJsonContentService, settingsIndex, documentId = Const.id) + +object MainSettingsIndexSource { + private object Const { + val id = "1" + val settingsKey = "settings" + } + + implicit val codec: Codec[RawRorSettings] = ??? +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 3ee1855749..564999973a 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.settings.source -import cats.Show import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError @@ -24,27 +23,29 @@ import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsErro sealed trait SettingsSource[SETTINGS] -trait ReadOnlySettingsSource[SETTINGS : Decoder] extends SettingsSource[SETTINGS] { - def load(): Task[Either[LoadingSettingsError, SETTINGS]] +trait ReadOnlySettingsSource[SETTINGS : Decoder, ERROR] extends SettingsSource[SETTINGS] { + def load(): Task[Either[LoadingSettingsError[ERROR], SETTINGS]] } object ReadOnlySettingsSource { - sealed trait LoadingSettingsError + sealed trait LoadingSettingsError[+ERROR] object LoadingSettingsError { - case object FormatError extends LoadingSettingsError -// final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError + case object FormatError extends LoadingSettingsError[Nothing] + final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError[ERROR] } - implicit val show: Show[LoadingSettingsError] = ??? + //implicit val show: Show[LoadingSettingsError[_]] = ??? } -trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder] extends ReadOnlySettingsSource[SETTINGS] { - def save(config: SETTINGS): Task[Either[SavingSettingsError, Unit]] +trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder, READ_SPECIFIC_ERROR, WRITE_SPECIFIC_ERROR] + extends ReadOnlySettingsSource[SETTINGS, READ_SPECIFIC_ERROR] { + + def save(settings: SETTINGS): Task[Either[SavingSettingsError[WRITE_SPECIFIC_ERROR], Unit]] } object ReadWriteSettingsSource { - sealed trait SavingSettingsError + sealed trait SavingSettingsError[+ERROR] object SavingSettingsError { -// final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError + final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError[ERROR] } - implicit val show: Show[SavingSettingsError] = ??? + // implicit val show: Show[SavingSettingsError] = ??? } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala new file mode 100644 index 0000000000..60be16d241 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala @@ -0,0 +1,206 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.source + +import eu.timepit.refined.types.string.NonEmptyString +import io.circe.{Codec, Decoder, Encoder} +import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService +import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} +import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks +import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthenticationServiceMock.ExternalAuthenticationUserMock +import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthorizationServiceMock.ExternalAuthorizationServiceUserMock +import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.LdapUserMock +import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} +import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId +import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} +import tech.beshu.ror.configuration.TestRorSettings.Expiration +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.es.IndexJsonContentService +import tech.beshu.ror.settings.source.TestSettingsIndexSource.Const +import tech.beshu.ror.syntax.* +import tech.beshu.ror.utils.DurationOps.* +import tech.beshu.ror.utils.json.KeyCodec + +import java.time.{Instant, ZoneOffset} +import java.time.format.DateTimeFormatter +import scala.concurrent.duration.Duration +import scala.util.{Failure, Success, Try} + +class TestSettingsIndexSource private(indexJsonContentService: IndexJsonContentService, + settingsIndex: RorSettingsIndex) + (implicit codec: Codec[TestRorSettings]) + extends IndexSettingsSource[TestRorSettings](indexJsonContentService, settingsIndex, documentId = Const.id) + +object TestSettingsIndexSource { + + def create(indexJsonContentService: IndexJsonContentService, + settingsIndex: RorSettingsIndex, + rorSettingsYamlParser: RawRorSettingsYamlParser): TestSettingsIndexSource = { + implicit val codec: Codec[TestRorSettings] = createTestRorSettingsCodec(rorSettingsYamlParser) + new TestSettingsIndexSource(indexJsonContentService, settingsIndex) + } + + private object Const { + val id = "2" + object properties { + val settings = "settings" + val expirationTtl = "expiration_ttl_millis" + val expirationTime = "expiration_timestamp" + val mocks = "auth_services_mocks" + } + } + + private def createTestRorSettingsCodec(yamlParser: RawRorSettingsYamlParser): Codec[TestRorSettings] = + Codec.from(decoder(yamlParser), encoder(yamlParser)) + + import Const.* + + private def encoder(implicit yamlParser: RawRorSettingsYamlParser): Encoder[TestRorSettings] = + Encoder.forProduct4(properties.settings, properties.mocks, properties.expirationTtl, properties.expirationTime){ + testRorSettings => ( + testRorSettings.rawSettings, + testRorSettings.mocks, + testRorSettings.expiration.ttl, + testRorSettings.expiration.validTo + ) + } + + private def decoder(implicit yamlParser: RawRorSettingsYamlParser): Decoder[TestRorSettings] = Decoder.instance { c => + for { + settings <- c.downField(properties.settings).as[RawRorSettings] + mocks <- c.downField(properties.mocks).as[AuthServicesMocks] + expirationTtl <- c.downField(properties.expirationTtl).as[PositiveFiniteDuration] + expirationTime <- c.downField(properties.expirationTime).as[Instant] + } yield TestRorSettings(settings, mocks, Expiration(expirationTtl, expirationTime)) + } + + private implicit def settingsCodec(implicit yamlParser: RawRorSettingsYamlParser): Codec[RawRorSettings] = { + val decoder = Decoder.decodeString.emap { str => + yamlParser + .fromString(str) + .left.map { _ => ??? } + } + val encoder: Encoder[RawRorSettings] = Encoder.encodeString.contramap(_.raw) + Codec.from(decoder, encoder) + } + + private implicit val mocksCodec: Codec[AuthServicesMocks] = { + implicit val nonEmptyStringCodec: Codec[NonEmptyString] = + Codec.from(Decoder.decodeString.emap(NonEmptyString.from), Encoder.encodeString.contramap(_.value)) + implicit val userIdCodec: Codec[User.Id] = + Codec.from(nonEmptyStringCodec.map(User.Id.apply), nonEmptyStringCodec.contramap(_.value)) + implicit val groupIdCodec: Codec[GroupId] = + Codec.from( + nonEmptyStringCodec.map(GroupId.apply), + nonEmptyStringCodec.contramap(_.value) + ) + + implicit val groupCodec: Codec[Group] = { + implicit val groupNameCodec: Codec[GroupName] = Codec.from( + nonEmptyStringCodec.map(GroupName.apply), + nonEmptyStringCodec.contramap(_.value) + ) + Codec.forProduct2("id", "name")(Group.apply)(group => (group.id, group.name)) + } + implicit val ldapServiceMock: Codec[LdapServiceMock] = { + implicit val userMock: Codec[LdapUserMock] = { + // "groups" left for backward compatibility + val encoder: Encoder[LdapUserMock] = Encoder.forProduct3("id", "groups", "userGroups")( + userMock => (userMock.id, userMock.groups.map(_.id), userMock.groups) + ) + val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => + LdapUserMock(id, groupIds.map(Group.from).toCovariantSet) + ) + val decoder: Decoder[LdapUserMock] = Decoder.forProduct2("id", "userGroups")(LdapUserMock.apply) + Codec.from(decoder.or(deprecatedFormatDecoder), encoder) + } + Codec.forProduct1("users")(LdapServiceMock.apply)(_.users) + } + + implicit val extAuthenticationMock: Codec[ExternalAuthenticationServiceMock] = { + implicit val userMock: Codec[ExternalAuthenticationUserMock] = + Codec.forProduct1("id")(ExternalAuthenticationUserMock.apply)(_.id) + Codec.forProduct1("users")(ExternalAuthenticationServiceMock.apply)(_.users) + } + + implicit val extAuthorizationMock: Codec[ExternalAuthorizationServiceMock] = { + implicit val userMock: Codec[ExternalAuthorizationServiceUserMock] = { + // "groups" left for backward compatibility + val encoder = Encoder.forProduct3("id", "groups", "userGroups")( + (userMock: ExternalAuthorizationServiceUserMock) => (userMock.id, userMock.groups.map(_.id), userMock.groups) + ) + val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => + ExternalAuthorizationServiceUserMock(id, groupIds.map(Group.from).toCovariantSet) + ) + val decoder = Decoder.forProduct2("id", "userGroups")(ExternalAuthorizationServiceUserMock.apply) + Codec.from(decoder.or(deprecatedFormatDecoder), encoder) + } + Codec.forProduct1("users")(ExternalAuthorizationServiceMock.apply)(_.users) + } + + implicit val ldapKeyCodec: KeyCodec[LdapService.Name] = KeyCodec.from[LdapService.Name]( + NonEmptyString.unapply(_).map(LdapService.Name.apply), + _.value.value + ) + + implicit val externalAuthenticationKeyCodec: KeyCodec[ExternalAuthenticationService.Name] = + KeyCodec.from[ExternalAuthenticationService.Name]( + NonEmptyString.unapply(_).map(ExternalAuthenticationService.Name.apply), + _.value.value + ) + + implicit val externalAuthorizationKeyCodec: KeyCodec[ExternalAuthorizationService.Name] = + KeyCodec.from[ExternalAuthorizationService.Name]( + NonEmptyString.unapply(_).map(ExternalAuthorizationService.Name.apply), + _.value.value + ) + + Codec.forProduct3( + "ldapMocks", + "externalAuthenticationMocks", + "externalAuthorizationMocks" + )(AuthServicesMocks.apply)(e => (e.ldapMocks, e.externalAuthenticationServiceMocks, e.externalAuthorizationServiceMocks)) + } + + private implicit lazy val expirationTtlDecoder: Codec[PositiveFiniteDuration] = { + val decoder = Decoder.decodeString.map { str => + Try { + Duration(str.toLong, "ms").toRefinedPositive match { + case Right(value) => value + case Left(errorMsg) => ??? + } + } match { + case Success(value) => value + case Failure(exception) => ??? + } + } + val encoder: Encoder[PositiveFiniteDuration] = Encoder.encodeString.contramap(_.value.toMillis.toString) + Codec.from(decoder, encoder) + } + + private implicit lazy val expirationTimeDecoder: Decoder[Instant] = { + val decoder = Decoder.decodeString.map { str => + Try(DateTimeFormatter.ISO_DATE_TIME.parse(str)).map(Instant.from) match { + case Success(value) => value + case Failure(exception) => ??? + } + } + val encoder: Encoder[Instant] = Encoder.encodeString.contramap(_.atOffset(ZoneOffset.UTC).toString) + Codec.from(decoder, encoder) + } + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala index 410dd8ac7f..534eec4e99 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala @@ -19,7 +19,6 @@ package tech.beshu.ror.settings.strategy import monix.eval.Task import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} class StartingRorSettingsLoadingStrategy(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], @@ -27,7 +26,7 @@ class StartingRorSettingsLoadingStrategy(mainSettingsIndexSource: IndexSettingsS testSettingsIndexSource: IndexSettingsSource[TestRorSettings], /* todo: retry strategy*/) { - def load(): Task[Either[StartingFailure, (RawRorSettings, TestRorSettings)]] = { + def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { mainSettingsIndexSource.toString mainSettingsFileSource.toString testSettingsIndexSource.toString @@ -77,8 +76,3 @@ class StartingRorSettingsLoadingStrategy(mainSettingsIndexSource: IndexSettingsS // } } -object StartingRorSettingsLoadingStrategy { - - type LoadingError = Either[LoadingSettingsError, LoadingSettingsError] - -} \ No newline at end of file From f5595a7c2179e5608515a0a39b76990972a5769a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 5 Sep 2025 14:10:02 +0200 Subject: [PATCH 030/103] wip --- .../ror/accesscontrol/domain/indices.scala | 8 + ...ettingsApi.scala => MainSettingsApi.scala} | 41 +++-- ...ettingsApi.scala => TestSettingsApi.scala} | 23 ++- .../tech/beshu/ror/boot/ReadonlyRest.scala | 67 +++----- .../tech/beshu/ror/boot/RorInstance.scala | 73 ++++----- .../SettingsRelatedCreatorsAndLoaders.scala | 65 ++++++++ .../boot/engines/BaseReloadableEngine.scala | 27 ++- .../MainSettingsBasedReloadableEngine.scala | 32 +++- .../TestSettingsBasedReloadableEngine.scala | 52 +++--- .../EsConfigBasedRorSettings.scala | 128 +++++++-------- .../ror/configuration/RorProperties.scala | 5 +- .../ror/configuration/RorSslSettings.scala | 12 +- ...ervice.scala => IndexDocumentReader.scala} | 18 +- .../settings/source/FileSettingsSource.scala | 22 ++- .../settings/source/IndexSettingsSource.scala | 45 ++--- .../source/MainSettingsFileSource.scala | 17 +- .../source/MainSettingsIndexSource.scala | 23 ++- .../settings/source/RawRorSettingsCodec.scala | 38 +++++ .../ror/settings/source/SettingsSource.scala | 2 +- .../source/TestSettingsIndexSource.scala | 23 +-- .../ForceLoadRorSettingsFromFileLoader.scala | 54 ++++++ ...hFileSourceFallbackRorSettingsLoader.scala | 154 ++++++++++++++++++ .../strategy/StartingRorSettingsLoader.scala | 26 +++ .../StartingRorSettingsLoadingStrategy.scala | 78 --------- .../unit/boot/ReadonlyRestStartingTests.scala | 104 ++++++------ .../beshu/ror/unit/boot/RorIndexTest.scala | 26 +-- .../beshu/ror/es/IndexLevelActionFilter.scala | 6 +- .../rradmin/RRAdminActionHandler.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 16 +- .../es/actions/rradmin/RRAdminResponse.scala | 8 +- .../RRTestConfigActionHandler.scala | 2 +- .../rrtestconfig/RRTestConfigRequest.scala | 16 +- .../rrtestconfig/RRTestConfigResponse.scala | 6 +- ...vice.scala => EsIndexDocumentReader.scala} | 45 ++--- 34 files changed, 779 insertions(+), 485 deletions(-) rename core/src/main/scala/tech/beshu/ror/api/{MainRorSettingsApi.scala => MainSettingsApi.scala} (85%) rename core/src/main/scala/tech/beshu/ror/api/{TestRorSettingsApi.scala => TestSettingsApi.scala} (94%) create mode 100644 core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala rename core/src/main/scala/tech/beshu/ror/es/{IndexJsonContentService.scala => IndexDocumentReader.scala} (58%) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala rename es90x/src/main/scala/tech/beshu/ror/es/services/{EsIndexJsonContentService.scala => EsIndexDocumentReader.scala} (72%) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala index 78ce8220d9..70d4efefba 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala @@ -22,11 +22,13 @@ import cats.implicits.* import com.github.benmanes.caffeine.cache.{Cache, Caffeine} import eu.timepit.refined.auto.* import eu.timepit.refined.types.string.NonEmptyString +import better.files.* import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Local import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Remote.ClusterName import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher.Matchable import tech.beshu.ror.accesscontrol.orders.requestedIndexOrder +import tech.beshu.ror.es.EsEnv import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.RefinedUtils.* import tech.beshu.ror.utils.ScalaOps.* @@ -532,3 +534,9 @@ final case class RorSettingsIndex(index: IndexName.Full) extends AnyVal { object RorSettingsIndex { val default: RorSettingsIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))) } + +final case class RorSettingsFile(file: File) extends AnyVal +object RorSettingsFile { + def default(esEnv: EsEnv): RorSettingsFile = RorSettingsFile(esEnv.configDir / "readonlyrest.yml") +} + diff --git a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala similarity index 85% rename from core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala rename to core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala index 7b446d239b..5e83edea9e 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala @@ -22,9 +22,9 @@ import io.circe.Decoder import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.MainRorSettingsApi.* -import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsRequest.Type -import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* +import tech.beshu.ror.api.MainSettingsApi.MainSettingsRequest.Type +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} @@ -32,14 +32,14 @@ import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps -class MainRorSettingsApi(rorInstance: RorInstance, - settingsYamlParser: RawRorSettingsYamlParser, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings]) +class MainSettingsApi(rorInstance: RorInstance, + settingsYamlParser: RawRorSettingsYamlParser, + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings]) extends Logging { - import MainRorSettingsApi.Utils.* - import MainRorSettingsApi.Utils.decoders.* + import MainSettingsApi.Utils.* + import MainSettingsApi.Utils.decoders.* def call(request: MainSettingsRequest) (implicit requestId: RequestId): Task[MainSettingsResponse] = { @@ -62,7 +62,7 @@ class MainRorSettingsApi(rorInstance: RorInstance, ForceReloadMainSettings.Success("ReadonlyREST settings were reloaded with success!") case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => ??? - //ForceReloadMainSettings.Failure(error.show) + //ForceReloadMainSettings.Failure(error.show) case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))) => ForceReloadMainSettings.Failure("Current settings are already loaded") case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)) => @@ -89,7 +89,7 @@ class MainRorSettingsApi(rorInstance: RorInstance, .map { case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) case Left(error) => ??? - // ProvideFileMainSettings.Failure(error.show) + // ProvideFileMainSettings.Failure(error.show) } } @@ -99,9 +99,9 @@ class MainRorSettingsApi(rorInstance: RorInstance, .map { case Right(settings) => ProvideIndexMainSettings.MainSettings(settings.raw) - // todo: ??? -// case Left(error@LoadingFromIndexError.IndexNotExist) => -// ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) + // todo: ??? + // case Left(error@LoadingFromIndexError.IndexNotExist) => + // ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) case Left(error) => ??? //ProvideIndexMainSettings.Failure(error.show) @@ -126,7 +126,7 @@ class MainRorSettingsApi(rorInstance: RorInstance, .leftMap { case IndexSettingsSavingError(error) => ??? - //UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") + //UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => UpdateIndexMainSettings.Failure(s"Current settings are already loaded") case ReloadError(RawSettingsReloadError.RorInstanceStopped) => @@ -137,7 +137,16 @@ class MainRorSettingsApi(rorInstance: RorInstance, } } -object MainRorSettingsApi { +object MainSettingsApi { + + final class Creator(settingsYamlParser: RawRorSettingsYamlParser, + mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], + mainSettingsFileSource: FileSettingsSource[RawRorSettings]) { + + def create(rorInstance: RorInstance): MainSettingsApi = { + new MainSettingsApi(rorInstance, settingsYamlParser, mainSettingsIndexSource, mainSettingsFileSource) + } + } final case class MainSettingsRequest(aType: MainSettingsRequest.Type, body: String) diff --git a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala similarity index 94% rename from core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala rename to core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala index bd20b4f7db..289b001217 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestRorSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala @@ -22,9 +22,9 @@ import io.circe.Decoder import monix.eval.Task import tech.beshu.ror.accesscontrol.blocks.ImpersonationWarning import tech.beshu.ror.accesscontrol.domain.{LoggedUser, RequestId} -import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsRequest.Type -import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse.* -import tech.beshu.ror.api.TestRorSettingsApi.{TestSettingsRequest, TestSettingsResponse} +import tech.beshu.ror.api.TestSettingsApi.TestSettingsRequest.Type +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* +import tech.beshu.ror.api.TestSettingsApi.{TestSettingsRequest, TestSettingsResponse} import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, RawSettingsReloadError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} @@ -37,11 +37,11 @@ import java.time.Instant import scala.concurrent.duration.* import scala.util.Try -class TestRorSettingsApi(rorInstance: RorInstance, - settingsYamlParser: RawRorSettingsYamlParser) { +class TestSettingsApi(rorInstance: RorInstance, + settingsYamlParser: RawRorSettingsYamlParser) { - import tech.beshu.ror.api.TestRorSettingsApi.Utils.* - import tech.beshu.ror.api.TestRorSettingsApi.Utils.decoders.* + import tech.beshu.ror.api.TestSettingsApi.Utils.* + import tech.beshu.ror.api.TestSettingsApi.Utils.decoders.* def call(request: RorApiRequest[TestSettingsRequest]) (implicit requestId: RequestId): Task[TestSettingsResponse] = { @@ -166,7 +166,14 @@ class TestRorSettingsApi(rorInstance: RorInstance, } } -object TestRorSettingsApi { +object TestSettingsApi { + + final class Creator(settingsYamlParser: RawRorSettingsYamlParser) { + + def create(rorInstance: RorInstance): TestSettingsApi = { + new TestSettingsApi(rorInstance, settingsYamlParser) + } + } final case class TestSettingsRequest(aType: TestSettingsRequest.Type, body: String) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 2e38320ede..3e65a7f490 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -25,6 +25,7 @@ import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.audit.{AuditingTool, LoggingContext} import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MutableMocksProviderWithCachePerRequest} +import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex import tech.beshu.ror.accesscontrol.factory.GlobalSettings.FlsEngine import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason @@ -33,16 +34,14 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} +import tech.beshu.ror.es.{EsEnv, IndexDocumentReader} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource, MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} -import tech.beshu.ror.settings.strategy.StartingRorSettingsLoadingStrategy import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant class ReadonlyRest(coreFactory: CoreFactory, - indexContentService: IndexJsonContentService, + indexContentService: IndexDocumentReader, auditSinkServiceCreator: AuditSinkServiceCreator, val esEnv: EsEnv) (implicit systemContext: SystemContext, @@ -51,53 +50,42 @@ class ReadonlyRest(coreFactory: CoreFactory, private[boot] val authServicesMocksProvider = new MutableMocksProviderWithCachePerRequest(AuthServicesMocks.empty) - def start(esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { + def start(esConfigBasedRorSettings: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - mainIndexSettingsSource <- lift(new MainSettingsIndexSource(indexContentService, esConfig.rorSettingsIndex)) - mainFileSettingsSource <- lift(new MainSettingsFileSource(???)) - testIndexSettingsSource <- lift(TestSettingsIndexSource.create(indexContentService, esConfig.rorSettingsIndex, ???)) - loadedSettings <- loadStartupSettings(mainIndexSettingsSource, mainFileSettingsSource, testIndexSettingsSource) + creatorsAndLoaders <- lift(SettingsRelatedCreatorsAndLoaders.create(esConfigBasedRorSettings, indexContentService)) + loadedSettings <- EitherT(creatorsAndLoaders.startingRorSettingsLoader.load()) (loadedMainRorSettings, loadedTestRorSettings) = loadedSettings - instance <- startRor(esConfig, loadedMainRorSettings, mainIndexSettingsSource, mainFileSettingsSource, loadedTestRorSettings, testIndexSettingsSource) + instance <- startRor(esConfigBasedRorSettings, creatorsAndLoaders.creators, loadedMainRorSettings, loadedTestRorSettings) } yield instance).value } - private def loadStartupSettings(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, (RawRorSettings, Option[TestRorSettings])] = { - val settingsLoader = new StartingRorSettingsLoadingStrategy(mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) - EitherT(settingsLoader.load()) - } - - private def startRor(esConfig: EsConfigBasedRorSettings, + private def startRor(esConfigBasedRorSettings: EsConfigBasedRorSettings, + creators: SettingsRelatedCreators, loadedMainRorSettings: RawRorSettings, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], - loadedTestRorSettings: Option[TestRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) = { + loadedTestRorSettings: Option[TestRorSettings]) = { for { - mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfig)) - testEngine <- EitherT.right(loadTestEngine(esConfig, loadedTestRorSettings)) - rorInstance <- createRorInstance(esConfig, mainEngine, mainSettingsIndexSource, mainSettingsFileSource, testEngine, testSettingsIndexSource, loadedMainRorSettings) + mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfigBasedRorSettings.settingsIndex)) + testEngine <- EitherT.right(loadTestEngine(loadedTestRorSettings, esConfigBasedRorSettings.settingsIndex)) + rorInstance <- createRorInstance(esConfigBasedRorSettings, creators, mainEngine, testEngine, loadedMainRorSettings) } yield rorInstance } - private def loadTestEngine(esConfig: EsConfigBasedRorSettings, - loadedTestRorSettings: Option[TestRorSettings]) = { + private def loadTestEngine(loadedTestRorSettings: Option[TestRorSettings], + settingsIndex: RorSettingsIndex) = { loadedTestRorSettings match { case None => Task.now(TestEngine.NotConfigured) case Some(settings) if !settings.isExpired(systemContext.clock) => - loadActiveTestEngine(esConfig, settings) + loadActiveTestEngine(settingsIndex, settings) case Some(settings) => loadInvalidatedTestEngine(settings) } } - private def loadActiveTestEngine(esConfig: EsConfigBasedRorSettings, testSettings: TestRorSettings) = { + private def loadActiveTestEngine(settingsIndex: RorSettingsIndex, testSettings: TestRorSettings) = { for { _ <- Task.delay(authServicesMocksProvider.update(testSettings.mocks)) - testEngine <- loadRorEngine(testSettings.rawSettings, esConfig) + testEngine <- loadRorEngine(testSettings.rawSettings, settingsIndex) .map { case Right(loadedEngine) => TestEngine.Configured( @@ -124,26 +112,24 @@ class ReadonlyRest(coreFactory: CoreFactory, TestEngine.Expiration(expiration.ttl, expiration.validTo) } - private def createRorInstance(esConfig: EsConfigBasedRorSettings, + private def createRorInstance(esConfigBasedRorSettings: EsConfigBasedRorSettings, + creators: SettingsRelatedCreators, mainEngine: Engine, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], testEngine: TestEngine, - testSettingsIndexSource: IndexSettingsSource[TestRorSettings], alreadyLoadedSettings: RawRorSettings) = { EitherT.right[StartingFailure] { - RorInstance.create(this, esConfig, MainEngine(mainEngine, alreadyLoadedSettings), testEngine, mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) + RorInstance.create(this, esConfigBasedRorSettings, creators, MainEngine(mainEngine, alreadyLoadedSettings), testEngine) } } - private[ror] def loadRorEngine(rorSettings: RawRorSettings, - esConfig: EsConfigBasedRorSettings): Task[Either[StartingFailure, Engine]] = { + private[ror] def loadRorEngine(settings: RawRorSettings, + settingsIndex: RorSettingsIndex): Task[Either[StartingFailure, Engine]] = { val httpClientsFactory = new AsyncHttpClientsFactory val ldapConnectionPoolProvider = new UnboundidLdapConnectionPoolProvider EitherT( coreFactory - .createCoreFrom(rorSettings, esConfig.rorSettingsIndex, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) + .createCoreFrom(settings, settingsIndex, httpClientsFactory, ldapConnectionPoolProvider, authServicesMocksProvider) ) .flatMap(core => createEngine(httpClientsFactory, ldapConnectionPoolProvider, core)) .semiflatTap { engine => @@ -220,6 +206,7 @@ class ReadonlyRest(coreFactory: CoreFactory, object ReadonlyRest { + // todo: move somewhere else final case class StartingFailure(message: String, throwable: Option[Throwable] = None) final case class MainEngine(engine: Engine, @@ -253,7 +240,7 @@ object ReadonlyRest { } } - def create(indexContentService: IndexJsonContentService, + def create(indexContentService: IndexDocumentReader, auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) (implicit scheduler: Scheduler, @@ -263,7 +250,7 @@ object ReadonlyRest { } def create(coreFactory: CoreFactory, - indexContentService: IndexJsonContentService, + indexContentService: IndexDocumentReader, auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) (implicit scheduler: Scheduler, diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 6ccd16bcd7..452c2f3106 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -28,14 +28,14 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.factory.RorDependencies -import tech.beshu.ror.api.{AuthMockApi, MainRorSettingsApi, TestRorSettingsApi} -import tech.beshu.ror.boot.engines.{Engines, MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} +import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} +import tech.beshu.ror.boot.engines.Engines import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -43,18 +43,17 @@ import java.time.Instant class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, - esConfig: EsConfigBasedRorSettings, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + creators: SettingsRelatedCreators, mainInitialEngine: ReadonlyRest.MainEngine, mainReloadInProgress: Semaphore[Task], - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], testInitialEngine: ReadonlyRest.TestEngine, - testReloadInProgress: Semaphore[Task], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) + testReloadInProgress: Semaphore[Task]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { + import creators.* import RorInstance.* import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} @@ -67,34 +66,30 @@ class RorInstance private(boot: ReadonlyRest, Cancelable.empty } - private val theMainSettingsEngine = new MainSettingsBasedReloadableEngine( + private val theMainSettingsEngine = mainSettingsBasedReloadableEngineCreator.create( boot, - esConfig, + esConfigBasedRorSettings, (mainInitialEngine.engine, mainInitialEngine.settings), - mainReloadInProgress, - mainSettingsIndexSource + mainReloadInProgress ) - private val theTestSettingsEngine = TestSettingsBasedReloadableEngine.create( + private val theTestSettingsEngine = testSettingsBasedReloadableEngineCreator.create( boot, - esConfig, + esConfigBasedRorSettings, testInitialEngine, - testReloadInProgress, - testSettingsIndexSource + testReloadInProgress ) - private val rarRorSettingsYamlParser = new RawRorSettingsYamlParser(esConfig.loadingRorCoreStrategy.rorSettingsMaxSize) - - private val mainSettingsRestApi = new MainRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser, mainSettingsIndexSource, mainSettingsFileSource) - private val testSettingsRestApi = new TestRorSettingsApi(rorInstance = this, rarRorSettingsYamlParser) + private val mainSettingsRestApi = mainSettingsApiCreator.create(this) + private val testSettingsRestApi = testSettingsApiCreator.create(this) private val authMockRestApi = new AuthMockApi(rorInstance = this) def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) - def mainSettingsApi: MainRorSettingsApi = mainSettingsRestApi + def mainSettingsApi: MainSettingsApi = mainSettingsRestApi def authMockApi: AuthMockApi = authMockRestApi - def testSettingsApi: TestRorSettingsApi = testSettingsRestApi + def testSettingsApi: TestSettingsApi = testSettingsRestApi def mocksProvider: MocksProvider = boot.authServicesMocksProvider @@ -215,29 +210,25 @@ class RorInstance private(boot: ReadonlyRest, object RorInstance { def create(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + creators: SettingsRelatedCreators, mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) + testEngine: ReadonlyRest.TestEngine) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - val mode = esConfig.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile(settings) => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(settings, _) => Mode.WithPeriodicIndexCheck(settings.refreshInterval) + val mode = esConfigBasedRorSettings.loadingRorCoreStrategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile => Mode.NoPeriodicIndexCheck + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters) => Mode.WithPeriodicIndexCheck(parameters.refreshInterval) } - createInstance(boot, esConfig, mode, mainEngine, testEngine, mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) + createInstance(boot, esConfigBasedRorSettings, creators, mode, mainEngine, testEngine) } private def createInstance(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + creators: SettingsRelatedCreators, mode: RorInstance.Mode, mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings]) + testEngine: ReadonlyRest.TestEngine) (implicit systemContext: SystemContext, scheduler: Scheduler) = { for { @@ -245,15 +236,13 @@ object RorInstance { isTestReloadInProgressSemaphore <- Semaphore[Task](1) } yield new RorInstance( boot = boot, - esConfig = esConfig, + esConfigBasedRorSettings = esConfigBasedRorSettings, + creators = creators, mode = mode, mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, - mainSettingsIndexSource = mainSettingsIndexSource, - mainSettingsFileSource = mainSettingsFileSource, - testSettingsIndexSource = testSettingsIndexSource, testInitialEngine = testEngine, - testReloadInProgress = isTestReloadInProgressSemaphore, + testReloadInProgress = isTestReloadInProgressSemaphore ) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala new file mode 100644 index 0000000000..4b49f9ff99 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -0,0 +1,65 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.boot + +import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} +import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.settings.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} +import tech.beshu.ror.settings.strategy.{ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} + +final class SettingsRelatedCreatorsAndLoaders private(val startingRorSettingsLoader: StartingRorSettingsLoader, + val creators: SettingsRelatedCreators) + +final class SettingsRelatedCreators(val mainSettingsBasedReloadableEngineCreator: MainSettingsBasedReloadableEngine.Creator, + val mainSettingsApiCreator: MainSettingsApi.Creator, + val testSettingsBasedReloadableEngineCreator: TestSettingsBasedReloadableEngine.Creator, + val testSettingsApiCreator: TestSettingsApi.Creator) + +object SettingsRelatedCreatorsAndLoaders { + + def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, + indexJsonContentService: IndexDocumentReader): SettingsRelatedCreatorsAndLoaders = { + val settingsYamlParser = new RawRorSettingsYamlParser(esConfigBasedRorSettings.settingsMaxSize) + val mainSettingsIndexSource = MainSettingsIndexSource.create( + indexJsonContentService, esConfigBasedRorSettings.settingsIndex, settingsYamlParser + ) + val mainSettingsFileSource = MainSettingsFileSource.create( + esConfigBasedRorSettings.settingsFile, settingsYamlParser + ) + val testSettingsIndexSource = TestSettingsIndexSource.create( + indexJsonContentService, esConfigBasedRorSettings.settingsIndex, settingsYamlParser + ) + val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { + case s@LoadingRorCoreStrategy.ForceLoadingFromFile => + new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) + case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_) => + new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) + } + new SettingsRelatedCreatorsAndLoaders( + startingSettingsLoader, + new SettingsRelatedCreators( + new MainSettingsBasedReloadableEngine.Creator(mainSettingsIndexSource), + new MainSettingsApi.Creator(settingsYamlParser, mainSettingsIndexSource, mainSettingsFileSource), + new TestSettingsBasedReloadableEngine.Creator(testSettingsIndexSource), + new TestSettingsApi.Creator(settingsYamlParser) + ) + ) + } +} diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index 1d9b4c3bf8..14d2f0dea4 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -41,7 +41,7 @@ import scala.language.postfixOps private[engines] abstract class BaseReloadableEngine(val name: String, boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, + esConfigBasedRorSettings: EsConfigBasedRorSettings, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task]) (implicit systemContext: SystemContext, @@ -252,18 +252,16 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } private def reloadWith(rorSettings: RawRorSettings, - expiration: Option[UpdatedExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithSettings] = EitherT { - tryToLoadRorCore(rorSettings) - .map(_ - .map { engine => - EngineWithSettings( - engine = engine, - settings = rorSettings, - expiration = expiration.map(engineExpiration) - ) - } - .leftMap(RawSettingsReloadError.ReloadingFailed.apply) - ) + expiration: Option[UpdatedExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithSettings] = { + EitherT(boot.loadRorEngine(rorSettings, esConfigBasedRorSettings.settingsIndex)) + .map { engine => + EngineWithSettings( + engine = engine, + settings = rorSettings, + expiration = expiration.map(engineExpiration) + ) + } + .leftMap(RawSettingsReloadError.ReloadingFailed.apply) } private def engineExpiration(expiration: UpdatedExpiration) = { @@ -275,9 +273,6 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } } - private def tryToLoadRorCore(rorSettings: RawRorSettings) = - boot.loadRorEngine(rorSettings, esConfig) - private def replaceCurrentEngine(newEngineWithSettings: EngineWithSettings) (implicit requestId: RequestId): EitherT[Task, RawSettingsReloadError, Unit] = { EitherT { diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index d036d6b462..010c85013b 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -31,20 +31,20 @@ import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource +import tech.beshu.ror.settings.source.{IndexSettingsSource, MainSettingsIndexSource} import tech.beshu.ror.utils.ScalaOps.value -private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - initialEngine: (Engine, RawRorSettings), - reloadInProgress: Semaphore[Task], - settingsSource: IndexSettingsSource[RawRorSettings]) - (implicit systemContext: SystemContext, - scheduler: Scheduler) +private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + initialEngine: (Engine, RawRorSettings), + reloadInProgress: Semaphore[Task], + settingsSource: IndexSettingsSource[RawRorSettings]) + (implicit systemContext: SystemContext, + scheduler: Scheduler) extends BaseReloadableEngine( name = "main", boot = boot, - esConfig = esConfig, + esConfigBasedRorSettings = esConfigBasedRorSettings, initialEngine = InitialEngine.Configured(engine = initialEngine._1, settings = initialEngine._2, expiration = None), reloadInProgress = reloadInProgress ) { @@ -130,3 +130,17 @@ private[boot] class MainSettingsBasedReloadableEngine(boot: ReadonlyRest, } } +object MainSettingsBasedReloadableEngine { + + final class Creator(settingsSource: MainSettingsIndexSource) { + + def create(boot: ReadonlyRest, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + initialEngine: (Engine, RawRorSettings), + reloadInProgress: Semaphore[Task]) + (implicit systemContext: SystemContext, + scheduler: Scheduler): MainSettingsBasedReloadableEngine = { + new MainSettingsBasedReloadableEngine(boot, esConfigBasedRorSettings, initialEngine, reloadInProgress, settingsSource) + } + } +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 42a12df16f..54678e71dc 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -32,7 +32,7 @@ import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource +import tech.beshu.ror.settings.source.{IndexSettingsSource, TestSettingsIndexSource} import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError @@ -40,13 +40,19 @@ import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, + esConfigBasedRorSettings: EsConfigBasedRorSettings, initialEngine: InitialEngine, reloadInProgress: Semaphore[Task], testSettingsSource: IndexSettingsSource[TestRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) - extends BaseReloadableEngine("test", boot, esConfig, initialEngine, reloadInProgress) { + extends BaseReloadableEngine( + name = "test", + boot = boot, + esConfigBasedRorSettings = esConfigBasedRorSettings, + initialEngine = initialEngine, + reloadInProgress = reloadInProgress + ) { def currentTestSettings() (implicit requestId: RequestId): Task[TestSettings] = { @@ -213,8 +219,9 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest .map(Some(_)) .leftFlatMap { // IndexSettingsReloadError.IndexLoadingSettingsError.apply // todo: - case LoadingSettingsError.FormatError => ??? + case LoadingSettingsError.SettingsMalformed(_) => ??? case LoadingSettingsError.SourceSpecificError(LoadingError.IndexNotFound) => ??? + case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound) => ??? } } @@ -238,23 +245,26 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } object TestSettingsBasedReloadableEngine { - def create(boot: ReadonlyRest, - esConfig: EsConfigBasedRorSettings, - initialEngine: ReadonlyRest.TestEngine, - reloadInProgress: Semaphore[Task], - testSettingsSource: IndexSettingsSource[TestRorSettings]) - (implicit systemContext: SystemContext, - scheduler: Scheduler): TestSettingsBasedReloadableEngine = { - val engine = initialEngine match { - case TestEngine.NotConfigured => - InitialEngine.NotConfigured - case TestEngine.Configured(engine, settings, expiration) => - InitialEngine.Configured(engine, settings, Some(engineExpiration(expiration))) - case TestEngine.Invalidated(settings, expiration) => - InitialEngine.Invalidated(settings, engineExpiration(expiration)) + + final class Creator(testSettingsSource: TestSettingsIndexSource) { + + def create(boot: ReadonlyRest, + esConfigBasedRorSettings: EsConfigBasedRorSettings, + initialEngine: ReadonlyRest.TestEngine, + reloadInProgress: Semaphore[Task]) + (implicit systemContext: SystemContext, + scheduler: Scheduler): TestSettingsBasedReloadableEngine = { + val engine = initialEngine match { + case TestEngine.NotConfigured => + InitialEngine.NotConfigured + case TestEngine.Configured(engine, settings, expiration) => + InitialEngine.Configured(engine, settings, Some(engineExpiration(expiration))) + case TestEngine.Invalidated(settings, expiration) => + InitialEngine.Invalidated(settings, engineExpiration(expiration)) + } + new TestSettingsBasedReloadableEngine(boot, esConfigBasedRorSettings, engine, reloadInProgress, testSettingsSource) } - new TestSettingsBasedReloadableEngine(boot, esConfig, engine, reloadInProgress, testSettingsSource) - } - private def engineExpiration(expiration: TestEngine.Expiration) = EngineExpiration(expiration.ttl, expiration.validTo) + private def engineExpiration(expiration: TestEngine.Expiration) = EngineExpiration(expiration.ttl, expiration.validTo) + } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala index bd0d06d698..ffdc9fb43c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala @@ -23,11 +23,10 @@ import io.circe.Decoder import monix.eval.Task import squants.information.Information import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError.{FileNotFound, MalformedContent, CannotUseRorSslWhenXPackSecurityIsEnabled} +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError.{CannotUseRorSslWhenXPackSecurityIsEnabled, FileNotFound, MalformedContent} import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy.{ForceLoadingFromFile, LoadFromIndexWithFileFallback} import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider @@ -37,7 +36,9 @@ import scala.language.implicitConversions final case class EsConfigBasedRorSettings(boot: RorBootSettings, ssl: Option[RorSslSettings], - rorSettingsIndex: RorSettingsIndex, + settingsIndex: RorSettingsIndex, + settingsFile: RorSettingsFile, + settingsMaxSize: Information, loadingRorCoreStrategy: LoadingRorCoreStrategy) object EsConfigBasedRorSettings { @@ -48,15 +49,13 @@ object EsConfigBasedRorSettings { val result = for { _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) bootSettings <- loadRorBootSettings(esEnv) - loadingRorCoreStrategyAndIndex <- loadLoadingRorCoreStrategyAndRorIndex(esEnv) - (loadingRorCoreStrategy, rorIndex) = loadingRorCoreStrategyAndIndex + loadingRorCoreStrategy <- loadLoadingRorCoreStrategy(esEnv) + settingsFile <- loadRorSettingsFile(esEnv) + settingsIndex <- loadRorSettingsIndex(esEnv) + settingsMaxSize <- loadMaxSizeInformation(esEnv) xpackSettings <- loadXpackSecuritySettings(esEnv, esEnv.isOssDistribution) - rorFileSettings = loadingRorCoreStrategy match { - case ForceLoadingFromFile(settings) => settings - case LoadFromIndexWithFileFallback(_, fallbackSettings) => fallbackSettings - } - sslSettings <- loadRorSslSettings(esEnv, rorFileSettings, xpackSettings) - } yield EsConfigBasedRorSettings(bootSettings, sslSettings, rorIndex, loadingRorCoreStrategy) + sslSettings <- loadRorSslSettings(esEnv, settingsFile, xpackSettings) + } yield EsConfigBasedRorSettings(bootSettings, sslSettings, settingsIndex, settingsFile, settingsMaxSize, loadingRorCoreStrategy) result.value } @@ -79,10 +78,10 @@ object EsConfigBasedRorSettings { } private def loadRorSslSettings(esEnv: EsEnv, - rorSettingsFromFileParameters: LoadFromFileParameters, + rorSettingsFile: RorSettingsFile, xpackSecurity: XpackSecurity) (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { - EitherT(RorSslSettings.load(rorSettingsFromFileParameters.rorSettingsFile, esEnv.elasticsearchYmlFile)) + EitherT(RorSslSettings.load(rorSettingsFile, esEnv.elasticsearchYmlFile)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) .subflatMap { case Some(ssl) if xpackSecurity.enabled => @@ -92,51 +91,53 @@ object EsConfigBasedRorSettings { } } - private def loadLoadingRorCoreStrategyAndRorIndex(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { + private def loadRorSettingsFile(esEnv: EsEnv) + (implicit systemContext: SystemContext) = { + implicit val decoder: Decoder[RorSettingsFile] = decoders.rorSettingsFileDecoder(esEnv) + load[RorSettingsFile](esEnv, "ROR configuration file name") + } + + private def loadRorSettingsIndex(esEnv: EsEnv) + (implicit systemContext: SystemContext) = { + import decoders.rorSettingsIndexDecoder + load[RorSettingsIndex](esEnv, "ROR configuration index settings") + } + + private def loadLoadingRorCoreStrategy(esEnv: EsEnv) + (implicit systemContext: SystemContext) = { + implicit val decoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) + load[LoadingRorCoreStrategy](esEnv, "ROR loading core settings") + } + + private def loadMaxSizeInformation(esEnv: EsEnv) + (implicit systemContext: SystemContext) = { + implicit val decoder: Decoder[Information] = decoders.settingsMaxSizeDecoder() + load[Information](esEnv, "ROR settings max size") + } + + private def load[T: Decoder](esEnv: EsEnv, settingsName: String) + (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, T] = { EitherT.fromEither[Task] { - implicit val loadRorCoreStrategyDecoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) - import decoders.rorSettingsIndexDecoder val loader = new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) for { strategy <- loader - .loadSettings[LoadingRorCoreStrategy](settingsName = "ROR loading core settings") - .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - rorIndex <- loader - .loadSettings[RorSettingsIndex](settingsName = "ROR configuration index settings") + .loadSettings[T](settingsName) .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - } yield (strategy, rorIndex) + } yield strategy } } sealed trait LoadingRorCoreStrategy object LoadingRorCoreStrategy { - final case class ForceLoadingFromFile(parameters: LoadFromFileParameters) extends LoadingRorCoreStrategy - final case class LoadFromIndexWithFileFallback(parameters: LoadFromIndexParameters, - fallbackParameters: LoadFromFileParameters) + case object ForceLoadingFromFile extends LoadingRorCoreStrategy + final case class LoadFromIndexWithFileFallback(parameters: LoadFromIndexParameters) // todo: what about retries? extends LoadingRorCoreStrategy } - implicit class ExtractFromLoadingRorSettingsStrategy(val strategy: LoadingRorCoreStrategy) extends AnyVal { - def rorSettingsFile: File = strategy match { - case ForceLoadingFromFile(parameters) => parameters.rorSettingsFile - case LoadFromIndexWithFileFallback(_, fallbackParameters) => fallbackParameters.rorSettingsFile - } - - def rorSettingsMaxSize: Information = strategy match { - case ForceLoadingFromFile(parameters) => parameters.settingsMaxSize - case LoadFromIndexWithFileFallback(parameters, _) => parameters.settingsMaxSize - } - } - - final case class LoadFromFileParameters(rorSettingsFile: File, - settingsMaxSize: Information) - final case class LoadFromIndexParameters(rorSettingsIndex: RorSettingsIndex, - refreshInterval: RefreshInterval, + final case class LoadFromIndexParameters(refreshInterval: RefreshInterval, loadingAttemptsInterval: LoadingAttemptsInterval, loadingAttemptsCount: LoadingAttemptsCount, - loadingDelay: LoadingDelay, - settingsMaxSize: Information) + loadingDelay: LoadingDelay) // todo: rename to reload or sth? private final case class XpackSecurity(enabled: Boolean) @@ -155,13 +156,11 @@ object EsConfigBasedRorSettings { default = false ) flatMap { case true => - loadFromFileParametersDecoder(esEnv, systemContext.propertiesProvider) - .map(LoadingRorCoreStrategy.ForceLoadingFromFile.apply) + Decoder.const(LoadingRorCoreStrategy.ForceLoadingFromFile) case false => for { loadFromIndexSettings <- loadFromIndexSettingsDecoder(systemContext.propertiesProvider) - loadFromFileSettings <- loadFromFileParametersDecoder(esEnv, systemContext.propertiesProvider) - } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(loadFromIndexSettings, loadFromFileSettings) + } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(loadFromIndexSettings) } } @@ -176,6 +175,21 @@ object EsConfigBasedRorSettings { ) } + implicit def rorSettingsFileDecoder(esEnv: EsEnv) + (implicit systemContext: SystemContext): Decoder[RorSettingsFile] = + Decoder.instance(_ => Right( + RorProperties + .rorSettingsCustomFile(systemContext.propertiesProvider) + .getOrElse(RorSettingsFile.default(esEnv)) + )) + + implicit def settingsMaxSizeDecoder() + (implicit systemContext: SystemContext): Decoder[Information] = { + Decoder.instance(_ => Right( + RorProperties.rorSettingsMaxSize(systemContext.propertiesProvider) + )) + } + def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecurity] = { if (isOssDistribution) { Decoder.const(XpackSecurity(enabled = false)) @@ -194,33 +208,17 @@ object EsConfigBasedRorSettings { } } - private implicit def loadFromFileParametersDecoder(esEnv: EsEnv, - propertiesProvider: PropertiesProvider): Decoder[LoadFromFileParameters] = { - for { - settingsFile <- Decoder.instance(_ => Right( - RorProperties.rorSettingsCustomFile(propertiesProvider).getOrElse(esEnv.configDir / "readonlyrest.yml") - )) - settingsMaxSize <- Decoder.instance(_ => Right( - RorProperties.rorSettingsMaxSize(propertiesProvider) - )) - } yield LoadFromFileParameters(settingsFile, settingsMaxSize) - } - private implicit def loadFromIndexSettingsDecoder(propertiesProvider: PropertiesProvider): Decoder[LoadFromIndexParameters] = { for { - settingsIndex <- rorSettingsIndexDecoder refreshInterval <- Decoder.instance(_ => Right(RorProperties.rorIndexSettingsReloadInterval(propertiesProvider))) loadingAttemptsInterval <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(propertiesProvider))) loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) - settingsMaxSize <- Decoder.instance(_ => Right(RorProperties.rorSettingsMaxSize(propertiesProvider))) } yield LoadFromIndexParameters( - settingsIndex, refreshInterval, loadingAttemptsInterval, loadingAttemptsCount, - loadingDelay, - settingsMaxSize + loadingDelay ) } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala index c63ae345d3..4ab4c0c532 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala @@ -23,6 +23,7 @@ import eu.timepit.refined.numeric.NonNegative import eu.timepit.refined.types.string.NonEmptyString import org.apache.logging.log4j.scala.Logging import squants.information.{Information, Megabytes} +import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.providers.PropertiesProvider.PropName @@ -53,10 +54,10 @@ object RorProperties extends Logging { val rorSettingsMaxSize: NonEmptyString = nes("com.readonlyrest.settings.maxSize") } - def rorSettingsCustomFile(implicit propertiesProvider: PropertiesProvider): Option[File] = + def rorSettingsCustomFile(implicit propertiesProvider: PropertiesProvider): Option[RorSettingsFile] = propertiesProvider .getProperty(PropName(keys.rorSettingsFilePath)) - .map(File(_)) + .map(f => RorSettingsFile(File(f))) def rorIndexSettingsReloadInterval(implicit propertiesProvider: PropertiesProvider): RefreshInterval = getProperty( diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala index 103b95e3b0..a992c89c86 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala @@ -21,6 +21,7 @@ import io.circe.{Decoder, DecodingFailure, HCursor} import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext +import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslSettings, FipsMode, InternodeSslSettings} import tech.beshu.ror.implicits.* @@ -56,7 +57,7 @@ object RorSslSettings extends Logging { } } - def load(rorSettingsFile: File, esConfigFile: File) + def load(rorSettingsFile: RorSettingsFile, esConfigFile: File) (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = Task { implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esConfigFile.parent) loadSslSettingsFrom(esConfigFile) @@ -72,12 +73,13 @@ object RorSslSettings extends Logging { ) } - private def fallbackToRorSettingsFile(rorSettingsFile: File) + private def fallbackToRorSettingsFile(rorSettingsFile: RorSettingsFile) (implicit decoder: Decoder[Option[RorSslSettings]], systemContext: SystemContext) = { - logger.info(s"... trying: ${rorSettingsFile.show}") - if (rorSettingsFile.exists) { - loadSslSettingsFrom(rorSettingsFile) + val settingsFile = rorSettingsFile.file + logger.info(s"... trying: ${settingsFile.show}") + if (settingsFile.exists) { + loadSslSettingsFrom(settingsFile) } else { Right(None) } diff --git a/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala b/core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala similarity index 58% rename from core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala rename to core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala index 332123813c..c0533d2ce5 100644 --- a/core/src/main/scala/tech/beshu/ror/es/IndexJsonContentService.scala +++ b/core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala @@ -19,21 +19,19 @@ package tech.beshu.ror.es import io.circe.Json import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.es.IndexJsonContentService.{ReadError, WriteError} +import tech.beshu.ror.es.IndexDocumentReader.{ReadError, WriteError} -trait IndexJsonContentService { - // todo: - def sourceOf(index: IndexName.Full, id: String): Task[Either[ReadError, Map[String, String]]] - def sourceOfAsString(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = ??? - def saveContent(index: IndexName.Full, id: String, content: Map[String, String]): Task[Either[WriteError, Unit]] - def saveContentJson(index: IndexName.Full, id: String, content: Json): Task[Either[WriteError, Unit]] = ??? +trait IndexDocumentReader { + def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] + def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] } -object IndexJsonContentService { +object IndexDocumentReader { sealed trait ReadError - case object ContentNotFound extends ReadError - case object CannotReachContentSource extends ReadError + case object IndexNotFound extends ReadError + case object DocumentNotFound extends ReadError + case object DocumentUnreachable extends ReadError sealed trait WriteError case object CannotWriteToIndex extends WriteError diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index 6395ad0e8c..db5ccccf05 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -20,37 +20,41 @@ import better.files.File import cats.data.EitherT import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} import monix.eval.Task +import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError -class FileSettingsSource[SETTINGS: Decoder](rorSettingsFile: File) +class FileSettingsSource[SETTINGS: Decoder](val settingsFile: File) extends ReadOnlySettingsSource[SETTINGS, FileSettingsSource.LoadingError] { - override def load(): Task[Either[LoadingSettingsError[FileSettingsSource.LoadingError], SETTINGS]] = { + override def load(): Task[Either[FileSettingsLoadingError, SETTINGS]] = { (for { - _ <- checkIfFileExist(rorSettingsFile) - settings <- loadSettingsFromFile(rorSettingsFile) + _ <- checkIfFileExist(settingsFile) + settings <- loadSettingsFromFile(settingsFile) } yield settings).value } - private def checkIfFileExist(file: File): EitherT[Task, LoadingSettingsError[FileSettingsSource.LoadingError], File] = + private def checkIfFileExist(file: File): EitherT[Task, FileSettingsLoadingError, File] = EitherT.cond(file.exists, file, SourceSpecificError(FileNotExist(file))) - private def loadSettingsFromFile(file: File): EitherT[Task, LoadingSettingsError[FileSettingsSource.LoadingError], SETTINGS] = { + private def loadSettingsFromFile(file: File): EitherT[Task, FileSettingsLoadingError, SETTINGS] = { EitherT - .pure[Task, LoadingSettingsError[FileSettingsSource.LoadingError]](file.contentAsString) + .pure[Task, FileSettingsLoadingError](file.contentAsString) .subflatMap { raw => parser .decode(raw) .left.map { - case ParsingFailure(_, _) => LoadingSettingsError.FormatError - case _: DecodingFailure => LoadingSettingsError.FormatError + case ParsingFailure(message, _) => LoadingSettingsError.SettingsMalformed(message) + case failure: DecodingFailure => LoadingSettingsError.SettingsMalformed(failure.message) } } } } object FileSettingsSource { + + type FileSettingsLoadingError = LoadingSettingsError[LoadingError] + sealed trait LoadingError object LoadingError { final case class FileNotExist(file: File) extends LoadingError diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index 3ad94f5f40..2446a53e9a 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -19,40 +19,41 @@ package tech.beshu.ror.settings.source import io.circe.syntax.* import io.circe.{Decoder, Encoder} import monix.eval.Task -import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.IndexNotFound +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.es.IndexDocumentReader.CannotWriteToIndex +import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.{DocumentNotFound, IndexNotFound} import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} +import tech.beshu.ror.settings.source.IndexSettingsSource.{IndexSettingsLoadingError, IndexSettingsSavingError, LoadingError, SavingError} import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError -class IndexSettingsSource[SETTINGS : Encoder : Decoder](indexJsonContentService: IndexJsonContentService, - settingsIndex: RorSettingsIndex, - documentId: String) +class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexJsonContentService: IndexDocumentReader, + val settingsIndex: IndexName.Full, + documentId: String) extends ReadWriteSettingsSource[SETTINGS, LoadingError, SavingError] { - override def load(): Task[Either[LoadingSettingsError[LoadingError], SETTINGS]] = { + override def load(): Task[Either[IndexSettingsLoadingError, SETTINGS]] = { indexJsonContentService - .sourceOfAsString(settingsIndex.index, documentId) + .documentAsJson(settingsIndex, documentId) .map { case Right(document) => - document - .as[SETTINGS] - .left.flatMap { _ => - settingsLoaderError(IndexNotFound) // todo: wrong type + document.as[SETTINGS] + .left.map { decodingFailure => + LoadingSettingsError.SettingsMalformed(decodingFailure.message) } - case Left(CannotReachContentSource) => - settingsLoaderError(IndexNotFound) - case Left(ContentNotFound) => + case Left(IndexDocumentReader.IndexNotFound) => settingsLoaderError(IndexNotFound) + case Left(IndexDocumentReader.DocumentNotFound) => + settingsLoaderError(DocumentNotFound) + case Left(IndexDocumentReader.DocumentUnreachable) => + settingsLoaderError(IndexNotFound) // todo: ??? } } - override def save(settings: SETTINGS): Task[Either[SavingSettingsError[SavingError], Unit]] = { + override def save(settings: SETTINGS): Task[Either[IndexSettingsSavingError, Unit]] = { indexJsonContentService - .saveContentJson(settingsIndex.index, documentId, settings.asJson) + .saveDocumentJson(settingsIndex, documentId, settings.asJson) .map { _.left.map { case CannotWriteToIndex => SavingSettingsError.SourceSpecificError(CannotSaveSettings) } } @@ -63,11 +64,17 @@ class IndexSettingsSource[SETTINGS : Encoder : Decoder](indexJsonContentService: } object IndexSettingsSource { + + type IndexSettingsLoadingError = LoadingSettingsError[LoadingError] + sealed trait LoadingError object LoadingError { case object IndexNotFound extends LoadingError + case object DocumentNotFound extends LoadingError } + type IndexSettingsSavingError = SavingSettingsError[SavingError] + sealed trait SavingError object SavingError { case object CannotSaveSettings extends SavingError diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala index a2aac9d727..521ec6a561 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala @@ -17,13 +17,18 @@ package tech.beshu.ror.settings.source import io.circe.Decoder -import tech.beshu.ror.configuration.RawRorSettings -import MainSettingsFileSource.decoder -import better.files.File +import tech.beshu.ror.accesscontrol.domain.RorSettingsFile +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -class MainSettingsFileSource(rorSettingsFile: File) - extends FileSettingsSource[RawRorSettings](rorSettingsFile) +class MainSettingsFileSource private (settingsFile: RorSettingsFile) + (implicit decoder: Decoder[RawRorSettings]) + extends FileSettingsSource[RawRorSettings](settingsFile.file) object MainSettingsFileSource { - implicit val decoder: Decoder[RawRorSettings] = ??? + + def create(settingsFile: RorSettingsFile, + settingsYamlParser: RawRorSettingsYamlParser): MainSettingsFileSource = { + implicit val decoder: Decoder[RawRorSettings] = new RawRorSettingsCodec(settingsYamlParser) + new MainSettingsFileSource(settingsFile) + } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala index 2141c75ca3..e83f170c9b 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala @@ -18,19 +18,26 @@ package tech.beshu.ror.settings.source import io.circe.Codec import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.settings.source.MainSettingsIndexSource.{Const, codec} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.settings.source.MainSettingsIndexSource.Const -class MainSettingsIndexSource(indexJsonContentService: IndexJsonContentService, - settingsIndex: RorSettingsIndex) - extends IndexSettingsSource[RawRorSettings](indexJsonContentService, settingsIndex, documentId = Const.id) +class MainSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, + settingsIndex: RorSettingsIndex) + (implicit codec: Codec[RawRorSettings]) + extends IndexSettingsSource[RawRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) object MainSettingsIndexSource { + + def create(indexJsonContentService: IndexDocumentReader, + settingsIndex: RorSettingsIndex, + settingsYamlParser: RawRorSettingsYamlParser): MainSettingsIndexSource = { + implicit val codec: Codec[RawRorSettings] = new RawRorSettingsCodec(settingsYamlParser) + new MainSettingsIndexSource(indexJsonContentService, settingsIndex) + } + private object Const { val id = "1" val settingsKey = "settings" } - - implicit val codec: Codec[RawRorSettings] = ??? } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala new file mode 100644 index 0000000000..ff115e0817 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala @@ -0,0 +1,38 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.source + +import io.circe.Decoder.Result +import io.circe.{Codec, Decoder, HCursor, Json} +import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} + +private [source] class RawRorSettingsCodec(yamlParser: RawRorSettingsYamlParser) + extends Codec[RawRorSettings] { + + override def apply(c: HCursor): Result[RawRorSettings] = + Decoder + .decodeString + .emap { str => + yamlParser + .fromString(str) + .left.map { _ => ??? } + } + .apply(c) + + override def apply(a: RawRorSettings): Json = + Json.fromString(a.raw) +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 564999973a..378ef2d533 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -29,7 +29,7 @@ trait ReadOnlySettingsSource[SETTINGS : Decoder, ERROR] extends SettingsSource[S object ReadOnlySettingsSource { sealed trait LoadingSettingsError[+ERROR] object LoadingSettingsError { - case object FormatError extends LoadingSettingsError[Nothing] + final case class SettingsMalformed(cause: String) extends LoadingSettingsError[Nothing] final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError[ERROR] } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala index 60be16d241..155b08a630 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} -import tech.beshu.ror.es.IndexJsonContentService +import tech.beshu.ror.es.IndexDocumentReader import tech.beshu.ror.settings.source.TestSettingsIndexSource.Const import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -40,17 +40,17 @@ import java.time.format.DateTimeFormatter import scala.concurrent.duration.Duration import scala.util.{Failure, Success, Try} -class TestSettingsIndexSource private(indexJsonContentService: IndexJsonContentService, +class TestSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, settingsIndex: RorSettingsIndex) (implicit codec: Codec[TestRorSettings]) - extends IndexSettingsSource[TestRorSettings](indexJsonContentService, settingsIndex, documentId = Const.id) + extends IndexSettingsSource[TestRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) object TestSettingsIndexSource { - def create(indexJsonContentService: IndexJsonContentService, + def create(indexJsonContentService: IndexDocumentReader, settingsIndex: RorSettingsIndex, - rorSettingsYamlParser: RawRorSettingsYamlParser): TestSettingsIndexSource = { - implicit val codec: Codec[TestRorSettings] = createTestRorSettingsCodec(rorSettingsYamlParser) + settingsYamlParser: RawRorSettingsYamlParser): TestSettingsIndexSource = { + implicit val codec: Codec[TestRorSettings] = createTestRorSettingsCodec(settingsYamlParser) new TestSettingsIndexSource(indexJsonContentService, settingsIndex) } @@ -88,15 +88,8 @@ object TestSettingsIndexSource { } yield TestRorSettings(settings, mocks, Expiration(expirationTtl, expirationTime)) } - private implicit def settingsCodec(implicit yamlParser: RawRorSettingsYamlParser): Codec[RawRorSettings] = { - val decoder = Decoder.decodeString.emap { str => - yamlParser - .fromString(str) - .left.map { _ => ??? } - } - val encoder: Encoder[RawRorSettings] = Encoder.encodeString.contramap(_.raw) - Codec.from(decoder, encoder) - } + private implicit def settingsCodec(implicit yamlParser: RawRorSettingsYamlParser): Codec[RawRorSettings] = + new RawRorSettingsCodec(yamlParser) private implicit val mocksCodec: Codec[AuthServicesMocks] = { implicit val nonEmptyStringCodec: Codec[NonEmptyString] = diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala new file mode 100644 index 0000000000..c4aea7d447 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala @@ -0,0 +1,54 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import cats.data.EitherT +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure +import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.FileSettingsSource +import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError +import tech.beshu.ror.utils.ScalaOps.* + +class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSource[RawRorSettings]) + extends StartingRorSettingsLoader with Logging { + + override def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { + val result = for { + _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${mainSettingsFileSource.settingsFile.show}")) + settings <- EitherT(mainSettingsFileSource.load()) + .leftMap(convertFileError) + .leftSemiflatTap { error => + logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") + } + } yield (settings, None) + result.value + } + + private def convertFileError(error: FileSettingsLoadingError): StartingFailure = { + ??? + // error match { + // case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) + // case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) + // } + } + + private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala new file mode 100644 index 0000000000..b1c5694520 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -0,0 +1,154 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import cats.data.EitherT +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure +import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.* +import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError +import tech.beshu.ror.settings.source.IndexSettingsSource.IndexSettingsLoadingError +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.utils.ScalaOps.* + +class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource: MainSettingsIndexSource, + mainSettingsFileSource: MainSettingsFileSource, + testSettingsIndexSource: TestSettingsIndexSource, + /* todo: retry strategy*/) + extends StartingRorSettingsLoader with Logging { + + override def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { + loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()).value + val result = for { + mainSettings <- loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()) + testSettings <- loadTestSettingsFromIndex().recover { case failure => Option.empty[TestRorSettings] } + } yield (mainSettings, testSettings) + result.value + } + + // todo: don't forget about porting this part of code: + // _ <- wait(parameters.loadingDelay.value.value) + private def loadMainSettingsFromIndex() = { + for { + _ <- lift(logger.info(s"Loading ReadonlyREST main settings from index (${mainSettingsIndexSource.settingsIndex.show}) ...")) + loadedSettings <- EitherT(mainSettingsIndexSource.load()) + .biSemiflatTap( + error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: "), // todo: ${error.show}") + // todo: + // case LoadingFromIndexError.IndexParsingError(message) => + // logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") + // case LoadingFromIndexError.IndexUnknownStructure => + // logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") + // case LoadingFromIndexError.IndexNotExist => + // logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.raw.show}") + ) + .leftMap(convertIndexError) + } yield loadedSettings + } + + private def convertIndexError(error: IndexSettingsLoadingError): StartingFailure = error match { + case LoadingSettingsError.SettingsMalformed(_) => ??? + case LoadingSettingsError.SourceSpecificError(IndexSettingsSource.LoadingError.IndexNotFound) => ??? + case LoadingSettingsError.SourceSpecificError(IndexSettingsSource.LoadingError.DocumentNotFound) => ??? + } + + private def loadMainSettingsFromFile() = { + for { + _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${mainSettingsFileSource.settingsFile.show}")) + loadedSettings <- EitherT(mainSettingsFileSource.load()) + .biSemiflatTap( + error => logger.dError(s"Loading ReadonlyREST settings from file failed:"), // todo: ${error.show}"), + settings => logger.dDebug(s"Loaded ReadonlyREST settings from index: ${settings.raw.show}") + ) + .leftMap(convertFileError) + } yield loadedSettings + } + + private def convertFileError(error: FileSettingsLoadingError): StartingFailure = error match { + case LoadingSettingsError.SettingsMalformed(_) => ??? + case LoadingSettingsError.SourceSpecificError(FileSettingsSource.LoadingError.FileNotExist(_)) => ??? + } + + private def loadTestSettingsFromIndex() = { + for { + _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${testSettingsIndexSource.settingsIndex.show}) ...")) + loadedSettings <- EitherT(testSettingsIndexSource.load()) + .biSemiflatTap( + error => logger.dInfo(s"Loading ReadonlyREST test settings from index failed: "), // todo: ${error.show}") + // todo: + // case LoadingFromIndexError.IndexParsingError(message) => + // logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") + // case LoadingFromIndexError.IndexUnknownStructure => + // logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") + // case LoadingFromIndexError.IndexNotExist => + // logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") + settings => logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${settings.rawSettings.raw.show}") + ) + .leftMap(convertIndexError) + .map(Option(_)) + } yield loadedSettings + } + + private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) + + // private def toStartingFailure(error: LoadingError) = { + // error match { + // case Left(LoadingSettingsError.FormatError) => + // StartingFailure(???) + // case Right(LoadingSettingsError.FormatError) => + // StartingFailure(???) + // // case Left(LoadingSettingsError.FileParsingError(message)) => + // // StartingFailure(message) + // // case Left(LoadingFromFileError.FileNotExist(file)) => + // // StartingFailure(s"Cannot find settings file: ${file.show}") + // // case Right(LoadingFromIndexError.IndexParsingError(message)) => + // // StartingFailure(message) + // // case Right(LoadingFromIndexError.IndexUnknownStructure) => + // // StartingFailure(s"Settings index is malformed") + // // case Right(LoadingFromIndexError.IndexNotExist) => + // // StartingFailure(s"Settings index doesn't exist") + // } + // } + // + // private def loadTestSettings(esConfigBasedRorSettings: EsConfigBasedRorSettings, + // indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { + // esConfig.loadingRorCoreStrategy match { + // case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => + // EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) + // case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => + // EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) + // .leftFlatMap { + // case LoadingSettingsError.FormatError => ??? + // // todo: + // // case LoadingFromIndexError.IndexParsingError(message) => + // // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") + // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + // // case LoadingFromIndexError.IndexUnknownStructure => + // // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") + // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + // // case LoadingFromIndexError.IndexNotExist => + // // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") + // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) + // } + // } + // } + +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala new file mode 100644 index 0000000000..ef124c07f9 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala @@ -0,0 +1,26 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.strategy + +import monix.eval.Task +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure +import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} + +trait StartingRorSettingsLoader { + + def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala deleted file mode 100644 index 534eec4e99..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoadingStrategy.scala +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.strategy - -import monix.eval.Task -import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} - -class StartingRorSettingsLoadingStrategy(mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings], - testSettingsIndexSource: IndexSettingsSource[TestRorSettings], - /* todo: retry strategy*/) { - - def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { - mainSettingsIndexSource.toString - mainSettingsFileSource.toString - testSettingsIndexSource.toString - ??? - } - -// private def toStartingFailure(error: LoadingError) = { -// error match { -// case Left(LoadingSettingsError.FormatError) => -// StartingFailure(???) -// case Right(LoadingSettingsError.FormatError) => -// StartingFailure(???) -// // case Left(LoadingSettingsError.FileParsingError(message)) => -// // StartingFailure(message) -// // case Left(LoadingFromFileError.FileNotExist(file)) => -// // StartingFailure(s"Cannot find settings file: ${file.show}") -// // case Right(LoadingFromIndexError.IndexParsingError(message)) => -// // StartingFailure(message) -// // case Right(LoadingFromIndexError.IndexUnknownStructure) => -// // StartingFailure(s"Settings index is malformed") -// // case Right(LoadingFromIndexError.IndexNotExist) => -// // StartingFailure(s"Settings index doesn't exist") -// } -// } -// -// private def loadTestSettings(esConfig: EsConfigBasedRorSettings, -// indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { -// esConfig.loadingRorCoreStrategy match { -// case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => -// EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) -// case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => -// EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) -// .leftFlatMap { -// case LoadingSettingsError.FormatError => ??? -// // todo: -// // case LoadingFromIndexError.IndexParsingError(message) => -// // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") -// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) -// // case LoadingFromIndexError.IndexUnknownStructure => -// // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") -// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) -// // case LoadingFromIndexError.IndexNotExist => -// // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") -// // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) -// } -// } -// } - -} diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 53cf722f4e..507d422486 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -51,8 +51,8 @@ import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} -import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound, WriteError} -import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexJsonContentService} +import tech.beshu.ror.es.IndexDocumentReader.{CannotReachContentSource, CannotWriteToIndex, DocumentNotFound, WriteError} +import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentReader} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -77,7 +77,7 @@ class ReadonlyRestStartingTests "support the main engine" should { "be loaded from file" when { "index is not available but file config is provided" in withReadonlyRest({ - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) @@ -93,7 +93,7 @@ class ReadonlyRestStartingTests acl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "file loading is forced in elasticsearch.yml" in withReadonlyRest({ - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) val coreFactory = mockCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading/readonlyrest.yml") @@ -109,7 +109,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) @@ -124,7 +124,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) @@ -143,7 +143,7 @@ class ReadonlyRestStartingTests val initialIndexConfigFile = "readonlyrest_initial.yml" val newIndexConfigFile = "readonlyrest_first.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + initialIndexConfigFile) val coreFactory = mock[CoreFactory] @@ -171,7 +171,7 @@ class ReadonlyRestStartingTests val firstNewIndexConfigFile = "readonlyrest_first.yml" val secondNewIndexConfigFile = "readonlyrest_second.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + initialIndexConfigFile) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) @@ -227,7 +227,7 @@ class ReadonlyRestStartingTests val originIndexConfigFile = "readonlyrest.yml" val updatedIndexConfigFile = "updated_readonlyrest.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] val coreFactory = mock[CoreFactory] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + originIndexConfigFile, repeatedCount = 1) @@ -253,7 +253,7 @@ class ReadonlyRestStartingTests } "failed to load" when { "force load from file is set and config is malformed" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexJsonContentService], "/boot_tests/forced_file_loading_malformed_config/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/forced_file_loading_malformed_config/") val result = readonlyRest.start().runSyncUnsafe() @@ -265,7 +265,7 @@ class ReadonlyRestStartingTests val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading_bad_config/readonlyrest.yml") val readonlyRest = readonlyRestBoot( factory = coreFactory, - indexJsonContentService = mockIndexJsonContentManagerSourceOfCallTestConfig(mock[IndexJsonContentService]), + indexJsonContentService = mockIndexJsonContentManagerSourceOfCallTestConfig(mock[IndexDocumentReader]), configPath = "/boot_tests/forced_file_loading_bad_config/" ) @@ -276,11 +276,11 @@ class ReadonlyRestStartingTests } } "index config doesn't exist and file config is malformed" in { - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexJsonContentManager, "/boot_tests/index_config_not_exists_malformed_file_config/") @@ -291,11 +291,11 @@ class ReadonlyRestStartingTests } } "index config doesn't exist and file config cannot be loaded" in { - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml") @@ -311,7 +311,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/malformed_index_config/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) @@ -327,7 +327,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/bad_index_config/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) @@ -341,7 +341,7 @@ class ReadonlyRestStartingTests } } "ROR SSL (in elasticsearch.yml) is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexJsonContentService], "/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") val result = readonlyRest.start().runSyncUnsafe() @@ -350,7 +350,7 @@ class ReadonlyRestStartingTests } } "ROR SSL (in readonlyrest.yml) is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexJsonContentService], "/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") val result = readonlyRest.start().runSyncUnsafe() @@ -359,7 +359,7 @@ class ReadonlyRestStartingTests } } "ROR FIPS SSL is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexJsonContentService], "/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") val result = readonlyRest.start().runSyncUnsafe() @@ -375,13 +375,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -398,7 +398,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -461,7 +461,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().minusSeconds(100) @@ -498,7 +498,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) @@ -521,7 +521,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().minusSeconds(100) @@ -552,7 +552,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) @@ -588,13 +588,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -640,13 +640,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -709,13 +709,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -792,13 +792,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -878,13 +878,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -927,7 +927,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -990,7 +990,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1054,7 +1054,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1118,12 +1118,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -1170,13 +1170,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) (mockedIndexJsonContentManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) @@ -1238,7 +1238,7 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1300,7 +1300,7 @@ class ReadonlyRestStartingTests "max size of ROR settings is exceeded" in { val readonlyRest = readonlyRestBoot( mock[CoreFactory], - mock[IndexJsonContentService], + mock[IndexDocumentReader], "/boot_tests/forced_file_loading/", maxYamlSize = Some("1 B") ) @@ -1313,7 +1313,7 @@ class ReadonlyRestStartingTests } } "unable to setup data stream audit output" in { - val mockedIndexJsonContentManager = mock[IndexJsonContentService] + val mockedIndexJsonContentManager = mock[IndexDocumentReader] mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) val dataStreamSinkConfig1 = AuditSink.Config.EsDataStreamBasedSink.default @@ -1396,7 +1396,7 @@ class ReadonlyRestStartingTests } private def readonlyRestBoot(factory: CoreFactory, - indexJsonContentService: IndexJsonContentService, + indexJsonContentService: IndexDocumentReader, configPath: String, auditSinkServiceCreator: AuditSinkServiceCreator = mock[AuditSinkServiceCreator], refreshInterval: Option[FiniteDuration] = None, @@ -1430,7 +1430,7 @@ class ReadonlyRestStartingTests ) } - private def mockIndexJsonContentManagerSourceOfCall(mockedManager: IndexJsonContentService, + private def mockIndexJsonContentManagerSourceOfCall(mockedManager: IndexDocumentReader, resourceFileName: String, repeatedCount: Int = 1) = { (mockedManager.sourceOf _) @@ -1442,15 +1442,15 @@ class ReadonlyRestStartingTests mockedManager } - private def mockIndexJsonContentManagerSourceOfCallTestConfig(mockedManager: IndexJsonContentService) = { + private def mockIndexJsonContentManagerSourceOfCallTestConfig(mockedManager: IndexDocumentReader) = { (mockedManager.sourceOf _) .expects(fullIndexName(".readonlyrest"), "2") .anyNumberOfTimes() - .returns(Task.now(Left(ContentNotFound))) + .returns(Task.now(Left(DocumentNotFound))) mockedManager } - private def mockIndexJsonContentManagerSaveCall(mockedManager: IndexJsonContentService, + private def mockIndexJsonContentManagerSaveCall(mockedManager: IndexDocumentReader, resourceFileName: String, saveResult: Task[Either[WriteError, Unit]] = Task.now(Right(()))) = { (mockedManager.saveContent _) diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index a20693d287..323563032e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.boot.RorInstance.TestSettings import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} +import tech.beshu.ror.es.{EsEnv, IndexDocumentReader} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -59,7 +59,7 @@ class RorIndexTest extends AnyWordSpec "no index is defined in config" should { "start ROR with default index name" in { val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) @@ -78,7 +78,7 @@ class RorIndexTest extends AnyWordSpec } "save ROR config in default index" in { val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) @@ -108,7 +108,7 @@ class RorIndexTest extends AnyWordSpec } "save ROR test config in default index" in { val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) @@ -140,7 +140,7 @@ class RorIndexTest extends AnyWordSpec "custom index is defined in config" should { "start ROR with custom index name" in { val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) @@ -158,7 +158,7 @@ class RorIndexTest extends AnyWordSpec } "save ROR config in custom index" in { val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) @@ -186,7 +186,7 @@ class RorIndexTest extends AnyWordSpec } "save ROR test config in custom index" in { val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexJsonContentService] + val indexJsonContentService = mock[IndexDocumentReader] mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) @@ -217,7 +217,7 @@ class RorIndexTest extends AnyWordSpec } private def readonlyRestBoot(factory: CoreFactory, - indexJsonContentService: IndexJsonContentService, + indexJsonContentService: IndexDocumentReader, configPath: String) = { implicit val systemContext: SystemContext = new SystemContext( propertiesProvider = TestsPropertiesProvider.usingMap( @@ -246,7 +246,7 @@ class RorIndexTest extends AnyWordSpec mockedCoreFactory } - private def mockMainRorConfigFromIndexLoading(indexJsonContentService: IndexJsonContentService, + private def mockMainRorConfigFromIndexLoading(indexJsonContentService: IndexDocumentReader, indexName: NonEmptyString) = { (indexJsonContentService.sourceOf _) .expects(fullIndexName(indexName), mainRorConfigDocumentId) @@ -254,15 +254,15 @@ class RorIndexTest extends AnyWordSpec .returns(Task.now(Right(Map("settings" -> indexRorConfig.raw)))) } - private def mockTestRorConfigFromIndexLoading(indexJsonContentService: IndexJsonContentService, + private def mockTestRorConfigFromIndexLoading(indexJsonContentService: IndexDocumentReader, indexName: NonEmptyString) = { (indexJsonContentService.sourceOf _) .expects(fullIndexName(indexName), testRorConfigDocumentId) .once() - .returns(Task.now(Left(IndexJsonContentService.ContentNotFound))) + .returns(Task.now(Left(IndexDocumentReader.DocumentNotFound))) } - private def mockMainRorConfigInIndexSaving(indexJsonContentService: IndexJsonContentService, + private def mockMainRorConfigInIndexSaving(indexJsonContentService: IndexDocumentReader, indexName: NonEmptyString) = { (indexJsonContentService.saveContent _) .expects(fullIndexName(indexName), mainRorConfigDocumentId, Map("settings" -> rorConfig.raw)) @@ -270,7 +270,7 @@ class RorIndexTest extends AnyWordSpec .returns(Task.now(Right(()))) } - private def mockTestRorConfigInIndexSaving(indexJsonContentService: IndexJsonContentService, + private def mockTestRorConfigInIndexSaving(indexJsonContentService: IndexDocumentReader, indexName: NonEmptyString) = { (indexJsonContentService.saveContent _) .expects( diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index fcce1bc399..ba2ed0880f 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -39,7 +39,7 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentReader, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.exceptions.StartingFailureException @@ -59,7 +59,7 @@ class IndexLevelActionFilter(nodeName: String, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - esConfig: EsConfigBasedRorSettings) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { @@ -69,7 +69,7 @@ class IndexLevelActionFilter(nodeName: String, new RorNotAvailableRequestHandler(esConfig.boot) private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentReader(client), auditSinkServiceCreator, EsEnvProvider.create(env) ) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 03e9a93a3c..cb70001ebe 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ec28c3351d..39d29c3160 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.MainRorSettingsApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: MainRorSettingsApi.MainSettingsRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: MainRorSettingsApi.MainSettingsRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -39,18 +39,18 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - MainRorSettingsApi.MainSettingsRequest.Type.ForceReload + MainSettingsApi.MainSettingsRequest.Type.ForceReload case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - MainRorSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - MainRorSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - MainRorSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new MainRorSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index e0e9061ba5..e2c2ac7402 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,12 +20,12 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.MainRorSettingsApi -import tech.beshu.ror.api.MainRorSettingsApi.MainSettingsResponse.* -import tech.beshu.ror.api.MainRorSettingsApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: MainRorSettingsApi.MainSettingsResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala index 06a4c37fec..753473156d 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala index cbe25cf2fd..ff76a4d3ce 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestRorSettingsApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestRorSettingsApi.TestSettingsRequest, +class RRTestConfigRequest(testConfigApiRequest: TestSettingsApi.TestSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestRorSettingsApi.TestSettingsRequest] = + def getTestConfigRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = RorApiRequest(testConfigApiRequest, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") @@ -41,18 +41,18 @@ object RRTestConfigRequest { def createFrom(request: RestRequest): RRTestConfigRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestRorSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestRorSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestRorSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestRorSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRTestConfigRequest( - TestRorSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala index 740ecc7259..03f4ba1d64 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala @@ -21,12 +21,12 @@ import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestRorSettingsApi -import tech.beshu.ror.api.TestRorSettingsApi.TestSettingsResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestRorSettingsApi.TestSettingsResponse) +class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { diff --git a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala similarity index 72% rename from es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala index 40ae6d97e0..39b39361c9 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.es.IndexDocumentReader.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentReader(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentReader with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) From 7c90dbf8b41030d1496f996b1a67c1f5d7c58539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Sat, 6 Sep 2025 23:36:31 +0200 Subject: [PATCH 031/103] wip --- .../tech/beshu/ror/api/AuthMockApi.scala | 2 +- .../tech/beshu/ror/api/MainSettingsApi.scala | 34 ++++--- .../tech/beshu/ror/api/TestSettingsApi.scala | 4 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 10 +- .../tech/beshu/ror/boot/RorInstance.scala | 9 +- .../boot/engines/BaseReloadableEngine.scala | 6 +- .../MainSettingsBasedReloadableEngine.scala | 34 +++---- .../TestSettingsBasedReloadableEngine.scala | 16 ++-- .../ror/configuration/MainRorSettings.scala | 20 ++++ .../index/IndexSettingsManager.scala | 75 ++++++++------- .../loader/RorSettingsLoader.scala | 54 +++++------ .../settings/source/FileSettingsSource.scala | 5 + .../settings/source/IndexSettingsSource.scala | 12 ++- .../source/MainSettingsFileSource.scala | 9 +- .../source/MainSettingsIndexSource.scala | 13 ++- .../settings/source/RawRorSettingsCodec.scala | 3 +- .../ror/settings/source/SettingsSource.scala | 14 ++- .../source/TestSettingsIndexSource.scala | 29 +++--- .../ForceLoadRorSettingsFromFileLoader.scala | 26 ++---- ...hFileSourceFallbackRorSettingsLoader.scala | 93 +++---------------- .../strategy/StartingRorSettingsLoader.scala | 4 +- 21 files changed, 217 insertions(+), 255 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index 059ed56ae0..5a95554583 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -163,7 +163,7 @@ class AuthMockApi(rorInstance: RorInstance) case Left(IndexSettingsUpdateError.TestSettingsInvalidated) => Left(AuthMockResponse.UpdateAuthMock.Invalidated(testSettingsInvalidatedMessage)) case Left(IndexSettingsUpdateError.IndexSettingsSavingError(error)) => - Left(AuthMockResponse.UpdateAuthMock.Failed(s"Cannot save auth services mocks: ")) // todo: ${error.show}")) + Left(AuthMockResponse.UpdateAuthMock.Failed(s"Cannot save auth services mocks: ${error.show}")) } } diff --git a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala index 5e83edea9e..5126a81db9 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.api +import cats.Show import cats.data.EitherT import cats.implicits.* import io.circe.Decoder @@ -28,14 +29,16 @@ import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.IndexNotFound +import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class MainSettingsApi(rorInstance: RorInstance, settingsYamlParser: RawRorSettingsYamlParser, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings]) + mainSettingsIndexSource: IndexSettingsSource[MainRorSettings], + mainSettingsFileSource: FileSettingsSource[MainRorSettings]) extends Logging { import MainSettingsApi.Utils.* @@ -61,8 +64,7 @@ class MainSettingsApi(rorInstance: RorInstance, case Right(()) => ForceReloadMainSettings.Success("ReadonlyREST settings were reloaded with success!") case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => - ??? - //ForceReloadMainSettings.Failure(error.show) + ForceReloadMainSettings.Failure(error.show) case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))) => ForceReloadMainSettings.Failure("Current settings are already loaded") case Left(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)) => @@ -87,9 +89,8 @@ class MainSettingsApi(rorInstance: RorInstance, mainSettingsFileSource .load() .map { - case Right(settings) => ProvideFileMainSettings.MainSettings(settings.raw) - case Left(error) => ??? - // ProvideFileMainSettings.Failure(error.show) + case Right(settings) => ProvideFileMainSettings.MainSettings(settings.rawSettings.raw) + case Left(error) => ProvideFileMainSettings.Failure(error.show) } } @@ -98,13 +99,11 @@ class MainSettingsApi(rorInstance: RorInstance, .load() .map { case Right(settings) => - ProvideIndexMainSettings.MainSettings(settings.raw) - // todo: ??? - // case Left(error@LoadingFromIndexError.IndexNotExist) => - // ProvideIndexMainSettings.MainSettingsNotFound(Show[LoadingFromIndexError].show(error)) + ProvideIndexMainSettings.MainSettings(settings.rawSettings.raw) + case Left(SourceSpecificError(error@IndexNotFound)) => + ProvideIndexMainSettings.MainSettingsNotFound(Show[IndexSettingsSource.LoadingError].show(error)) case Left(error) => - ??? - //ProvideIndexMainSettings.Failure(error.show) + ProvideIndexMainSettings.Failure(error.show) } } @@ -125,8 +124,7 @@ class MainSettingsApi(rorInstance: RorInstance, EitherT(rorInstance.forceReloadAndSave(settings)) .leftMap { case IndexSettingsSavingError(error) => - ??? - //UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") + UpdateIndexMainSettings.Failure(s"Cannot save new settings: ${error.show}") case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => UpdateIndexMainSettings.Failure(s"Current settings are already loaded") case ReloadError(RawSettingsReloadError.RorInstanceStopped) => @@ -140,8 +138,8 @@ class MainSettingsApi(rorInstance: RorInstance, object MainSettingsApi { final class Creator(settingsYamlParser: RawRorSettingsYamlParser, - mainSettingsIndexSource: IndexSettingsSource[RawRorSettings], - mainSettingsFileSource: FileSettingsSource[RawRorSettings]) { + mainSettingsIndexSource: IndexSettingsSource[MainRorSettings], + mainSettingsFileSource: FileSettingsSource[MainRorSettings]) { def create(rorInstance: RorInstance): MainSettingsApi = { new MainSettingsApi(rorInstance, settingsYamlParser, mainSettingsIndexSource, mainSettingsFileSource) diff --git a/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala index 289b001217..872b9cf568 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala @@ -86,7 +86,7 @@ class TestSettingsApi(rorInstance: RorInstance, case Right(()) => TestSettingsResponse.InvalidateTestSettings.SuccessResponse("ROR Test settings are invalidated") case Left(IndexSettingsInvalidationError.IndexSettingsSavingError(error)) => - TestSettingsResponse.InvalidateTestSettings.FailedResponse(s"Cannot invalidate test settings: ") // todo: ${error.show}") + TestSettingsResponse.InvalidateTestSettings.FailedResponse(s"Cannot invalidate test settings: ${error.show}") } } @@ -144,7 +144,7 @@ class TestSettingsApi(rorInstance: RorInstance, } .leftMap { case IndexSettingsSavingError(error) => - TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ") // todo: ${error.show}") + TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Cannot reload new settings: ${error.show}") case ReloadError(RawSettingsReloadError.SettingsUpToDate(_)) => TestSettingsResponse.UpdateTestSettings.FailedResponse(s"Current settings are already loaded") case ReloadError(RawSettingsReloadError.RorInstanceStopped) => diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 3e65a7f490..0e84633414 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -61,10 +61,10 @@ class ReadonlyRest(coreFactory: CoreFactory, private def startRor(esConfigBasedRorSettings: EsConfigBasedRorSettings, creators: SettingsRelatedCreators, - loadedMainRorSettings: RawRorSettings, + loadedMainRorSettings: MainRorSettings, loadedTestRorSettings: Option[TestRorSettings]) = { for { - mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings, esConfigBasedRorSettings.settingsIndex)) + mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings.rawSettings, esConfigBasedRorSettings.settingsIndex)) testEngine <- EitherT.right(loadTestEngine(loadedTestRorSettings, esConfigBasedRorSettings.settingsIndex)) rorInstance <- createRorInstance(esConfigBasedRorSettings, creators, mainEngine, testEngine, loadedMainRorSettings) } yield rorInstance @@ -116,9 +116,9 @@ class ReadonlyRest(coreFactory: CoreFactory, creators: SettingsRelatedCreators, mainEngine: Engine, testEngine: TestEngine, - alreadyLoadedSettings: RawRorSettings) = { + alreadyLoadedSettings: MainRorSettings) = { EitherT.right[StartingFailure] { - RorInstance.create(this, esConfigBasedRorSettings, creators, MainEngine(mainEngine, alreadyLoadedSettings), testEngine) + RorInstance.create(this, esConfigBasedRorSettings, creators, MainEngine(mainEngine, alreadyLoadedSettings.rawSettings), testEngine) } } @@ -197,8 +197,6 @@ class ReadonlyRest(coreFactory: CoreFactory, StartingFailure(errorsMessage) } - //todo: private def notSetTestRorSettings: TestRorSettings = TestRorSettings.NotSet - private def lift[A](value: => A) = { EitherT.liftF(Task.delay(value)) } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 452c2f3106..b0f8ea62f8 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -32,7 +32,7 @@ import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.Engines import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, MainRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.IndexSettingsSource import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError @@ -69,7 +69,7 @@ class RorInstance private(boot: ReadonlyRest, private val theMainSettingsEngine = mainSettingsBasedReloadableEngineCreator.create( boot, esConfigBasedRorSettings, - (mainInitialEngine.engine, mainInitialEngine.settings), + mainInitialEngine, mainReloadInProgress ) private val theTestSettingsEngine = testSettingsBasedReloadableEngineCreator.create( @@ -99,7 +99,7 @@ class RorInstance private(boot: ReadonlyRest, def forceReloadAndSave(settings: RawRorSettings) (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, Unit]] = - theMainSettingsEngine.forceReloadAndSave(settings) + theMainSettingsEngine.forceReloadAndSave(MainRorSettings(settings)) def currentTestSettings() (implicit requestId: RequestId): Task[TestSettings] = { @@ -143,6 +143,7 @@ class RorInstance private(boot: ReadonlyRest, scheduleIndexSettingsChecking(interval, reloadTask) } + // todo: check messages private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Cancelable = { logger.debug(s"[CLUSTERWIDE SETTINGS] Scheduling next in-index settings check within ${interval.show}") @@ -173,7 +174,7 @@ class RorInstance private(boot: ReadonlyRest, case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") case (name, Left(EngineReloadError(IndexSettingsReloadError.IndexLoadingSettingsError(error)))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed:") // todo: ${error.show}") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") } private def tryMainEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index 14d2f0dea4..c466a3bb98 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -416,11 +416,9 @@ private[engines] abstract class BaseReloadableEngine(val name: String, object BaseReloadableEngine { - //private[engines] // todo: uncomment - sealed trait InitialEngine + private[engines] sealed trait InitialEngine - //private[engines] // todo: uncomment - object InitialEngine { + private[engines] object InitialEngine { case object NotConfigured extends InitialEngine final case class Configured(engine: Engine, settings: RawRorSettings, diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 010c85013b..03c9420cad 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -29,16 +29,18 @@ import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{Index import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, MainRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError import tech.beshu.ror.settings.source.{IndexSettingsSource, MainSettingsIndexSource} import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest, esConfigBasedRorSettings: EsConfigBasedRorSettings, - initialEngine: (Engine, RawRorSettings), + initialEngine: MainEngine, reloadInProgress: Semaphore[Task], - settingsSource: IndexSettingsSource[RawRorSettings]) + settingsSource: IndexSettingsSource[MainRorSettings]) (implicit systemContext: SystemContext, scheduler: Scheduler) extends BaseReloadableEngine( @@ -49,30 +51,30 @@ private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest reloadInProgress = reloadInProgress ) { - def forceReloadAndSave(settings: RawRorSettings) + def forceReloadAndSave(settings: MainRorSettings) (implicit requestId: RequestId): Task[Either[IndexSettingsReloadWithUpdateError, Unit]] = { for { - _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${settings.hashString()}) ...")) + _ <- Task.delay(logger.info(s"[${requestId.show}] Reloading of provided settings was forced (new engine id=${settings.rawSettings.hashString()}) ...")) reloadResult <- reloadInProgress.withPermit { value { for { - _ <- reloadEngine(settings).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) + _ <- reloadEngine(settings.rawSettings).leftMap(IndexSettingsReloadWithUpdateError.ReloadError.apply) _ <- saveSettings(settings) } yield () } } _ <- Task.delay(reloadResult match { case Right(_) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) settings reloaded!") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.rawSettings.hashString().show}) settings reloaded!") case Left(ReloadError(SettingsUpToDate(oldSettings))) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${oldSettings.hashString().show}) already loaded!") case Left(ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => - logger.error(s"[${requestId.show}] [${settings.hashString()}] Cannot reload ROR settings - failure: ${message.show}", ex) + logger.error(s"[${requestId.show}] [${settings.rawSettings.hashString()}] Cannot reload ROR settings - failure: ${message.show}", ex) case Left(ReloadError(ReloadingFailed(StartingFailure(message, None)))) => logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${message.show}") case Left(ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") - case Left(IndexSettingsSavingError(_)) => // todo: SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(SourceSpecificError(CannotSaveSettings))) => // todo: invalidate created core? logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") }) @@ -86,7 +88,7 @@ private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest reloadResult <- reloadEngineUsingIndexSettings() _ <- Task.delay(reloadResult match { case Right(settings) => - logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) settings reloaded!") + logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.rawSettings.hashString().show}) settings reloaded!") case Left(IndexSettingsReloadError.ReloadError(SettingsUpToDate(settings))) => logger.info(s"[${requestId.show}] ROR ${name.show} engine (id=${settings.hashString().show}) already loaded!") case Left(IndexSettingsReloadError.ReloadError(ReloadingFailed(StartingFailure(message, Some(ex))))) => @@ -96,23 +98,23 @@ private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest case Left(IndexSettingsReloadError.ReloadError(RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading main settings skipped!") case Left(IndexSettingsReloadError.IndexLoadingSettingsError(error)) => - logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ") // ${error.show}") // todo: + logger.error(s"[${requestId.show}] Cannot reload ROR settings - failure: ${error.show}") }) } yield reloadResult.map(_ => ()) } private def reloadEngineUsingIndexSettings() - (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, MainRorSettings]] = { reloadInProgress.withPermit { reloadEngineUsingIndexSettingsWithoutPermit() } } private[boot] def reloadEngineUsingIndexSettingsWithoutPermit() - (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, RawRorSettings]] = { + (implicit requestId: RequestId): Task[Either[IndexSettingsReloadError, MainRorSettings]] = { val result = for { newSettings <- loadRorSettingFromIndex() - _ <- reloadEngine(newSettings) + _ <- reloadEngine(newSettings.rawSettings) .leftMap(IndexSettingsReloadError.ReloadError.apply) .leftWiden[IndexSettingsReloadError] } yield newSettings @@ -124,7 +126,7 @@ private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest .leftMap(IndexSettingsReloadError.IndexLoadingSettingsError.apply) } - private def saveSettings(settings: RawRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { + private def saveSettings(settings: MainRorSettings): EitherT[Task, IndexSettingsReloadWithUpdateError, Unit] = { EitherT(settingsSource.save(settings)) .leftMap(IndexSettingsReloadWithUpdateError.IndexSettingsSavingError.apply) } @@ -136,7 +138,7 @@ object MainSettingsBasedReloadableEngine { def create(boot: ReadonlyRest, esConfigBasedRorSettings: EsConfigBasedRorSettings, - initialEngine: (Engine, RawRorSettings), + initialEngine: MainEngine, reloadInProgress: Semaphore[Task]) (implicit systemContext: SystemContext, scheduler: Scheduler): MainSettingsBasedReloadableEngine = { diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 54678e71dc..182e11ad44 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -32,10 +32,12 @@ import tech.beshu.ror.boot.engines.SettingsHash.* import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.source.{IndexSettingsSource, TestSettingsIndexSource} import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value @@ -111,7 +113,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest logger.error(s"[${requestId.show}] Cannot reload ROR test settings - failure: ${message.show}") case Left(ReloadError(RawSettingsReloadError.RorInstanceStopped)) => logger.warn(s"[${requestId.show}] ROR is being stopped! Loading tests settings skipped!") - case Left(IndexSettingsSavingError(_)) => // todo: SavingIndexSettingsError.CannotSaveSettings)) => + case Left(IndexSettingsSavingError(SourceSpecificError(CannotSaveSettings))) => logger.error(s"[${requestId.show}] Saving ROR test settings in index failed") }) } yield reloadResult @@ -170,7 +172,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } private def readCurrentTestSettingsForUpdate() - (implicit requestId: RequestId): EitherT[Task, IndexSettingsUpdateError, TestSettings.Present] = { + (implicit requestId: RequestId): EitherT[Task, IndexSettingsUpdateError, TestSettings.Present] = { EitherT { currentTestSettings() .map { @@ -218,15 +220,15 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest EitherT(testSettingsSource.load()) .map(Some(_)) .leftFlatMap { - // IndexSettingsReloadError.IndexLoadingSettingsError.apply // todo: - case LoadingSettingsError.SettingsMalformed(_) => ??? - case LoadingSettingsError.SourceSpecificError(LoadingError.IndexNotFound) => ??? - case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound) => ??? + case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound) => + EitherT.rightT(None) + case error => + EitherT.leftT(IndexSettingsReloadError.IndexLoadingSettingsError(error): IndexSettingsReloadError) } } private def invalidateTestSettingsByIndex[A]() - (implicit requestId: RequestId): EitherT[Task, A, Unit] = { + (implicit requestId: RequestId): EitherT[Task, A, Unit] = { EitherT.right[A] { for { _ <- diff --git a/core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala new file mode 100644 index 0000000000..dfed1b4972 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala @@ -0,0 +1,20 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.configuration + +final case class MainRorSettings(rawSettings: RawRorSettings) + diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala index 469fa9edf2..eeb904fe20 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala @@ -14,41 +14,40 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.index - -import monix.eval.Task -import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.configuration.RawRorSettingsYamlParser -import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -import tech.beshu.ror.configuration.loader.RorSettingsLoader -import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError - -// todo: maybe we need settings manager to encapsulate file and index loading/saving logic? -// todo: it looks like this manager should extend RorConfigLoader -trait IndexSettingsManager[SETTINGS] { - - def settingsIndex: RorSettingsIndex - - def rorSettingsYamlParser: RawRorSettingsYamlParser - - def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] - - def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] - - // todo: is this ok? - protected final def settingsLoaderError(error: LoadingIndexSettingsError): Task[Either[SpecializedError[LoadingIndexSettingsError], SETTINGS]] = - Task.now(Left(SpecializedError[LoadingIndexSettingsError](error))) -} -object IndexSettingsManager { - - sealed trait LoadingIndexSettingsError - object LoadingIndexSettingsError { - case object IndexNotExist extends LoadingIndexSettingsError - case object UnknownStructureOfIndexDocument extends LoadingIndexSettingsError - } - - sealed trait SavingIndexSettingsError - object SavingIndexSettingsError { - case object CannotSaveSettings extends SavingIndexSettingsError - } -} +//package tech.beshu.ror.configuration.index +// +//import monix.eval.Task +//import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex +//import tech.beshu.ror.configuration.RawRorSettingsYamlParser +//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} +//import tech.beshu.ror.configuration.loader.RorSettingsLoader +//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError +// +//trait IndexSettingsManager[SETTINGS] { +// +// def settingsIndex: RorSettingsIndex +// +// def rorSettingsYamlParser: RawRorSettingsYamlParser +// +// def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] +// +// def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] +// +// protected final def settingsLoaderError(error: LoadingIndexSettingsError): Task[Either[SpecializedError[LoadingIndexSettingsError], SETTINGS]] = +// Task.now(Left(SpecializedError[LoadingIndexSettingsError](error))) +//} +//object IndexSettingsManager { +// +// sealed trait LoadingIndexSettingsError +// object LoadingIndexSettingsError { +// case object IndexNotExist extends LoadingIndexSettingsError +// case object UnknownStructureOfIndexDocument extends LoadingIndexSettingsError +// } +// +// sealed trait SavingIndexSettingsError +// object SavingIndexSettingsError { +// case object CannotSaveSettings extends SavingIndexSettingsError +// } +//} + +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala index ca4db9961c..abaf26fd1a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala @@ -14,31 +14,31 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration.loader +//package tech.beshu.ror.configuration.loader +// +//import cats.Show +//import monix.eval.Task +//import tech.beshu.ror.configuration.RawRorSettings +//import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError +// +//trait RorSettingsLoader[SPECIALIZED_ERROR] { +// +// def load(): Task[Either[RorSettingsLoader.Error[SPECIALIZED_ERROR], RawRorSettings]] +//} +// +//object RorSettingsLoader { +// +// sealed trait Error[+SPECIALIZED_ERROR] +// object Error { +// final case class ParsingError(error: ParsingRorSettingsError) extends Error[Nothing] +// final case class SpecializedError[ERROR](error: ERROR) extends Error[ERROR] +// +// implicit def show[E: Show]: Show[Error[E]] = Show.show { +// case ParsingError(error) => Show[ParsingRorSettingsError].show(error) +// case SpecializedError(error) => Show[E].show(error) +// } +// } +// +//} -import cats.Show -import monix.eval.Task -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError - -// todo: do we need it? -trait RorSettingsLoader[SPECIALIZED_ERROR] { - - def load(): Task[Either[RorSettingsLoader.Error[SPECIALIZED_ERROR], RawRorSettings]] -} - -object RorSettingsLoader { - - sealed trait Error[+SPECIALIZED_ERROR] - object Error { - final case class ParsingError(error: ParsingRorSettingsError) extends Error[Nothing] - final case class SpecializedError[ERROR](error: ERROR) extends Error[ERROR] - - // todo: move? - implicit def show[E: Show]: Show[Error[E]] = Show.show { - case ParsingError(error) => Show[ParsingRorSettingsError].show(error) - case SpecializedError(error) => Show[E].show(error) - } - } - -} +// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index db5ccccf05..d1dc199fe3 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -17,6 +17,7 @@ package tech.beshu.ror.settings.source import better.files.File +import cats.Show import cats.data.EitherT import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} import monix.eval.Task @@ -58,5 +59,9 @@ object FileSettingsSource { sealed trait LoadingError object LoadingError { final case class FileNotExist(file: File) extends LoadingError + + implicit val show: Show[LoadingError] = Show.show { + case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" + } } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index 2446a53e9a..3ffee05de4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.settings.source +import cats.Show import io.circe.syntax.* import io.circe.{Decoder, Encoder} import monix.eval.Task @@ -47,7 +48,7 @@ class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexJsonContentService: case Left(IndexDocumentReader.DocumentNotFound) => settingsLoaderError(DocumentNotFound) case Left(IndexDocumentReader.DocumentUnreachable) => - settingsLoaderError(IndexNotFound) // todo: ??? + settingsLoaderError(IndexNotFound) // todo: throw ex? } } @@ -71,6 +72,11 @@ object IndexSettingsSource { object LoadingError { case object IndexNotFound extends LoadingError case object DocumentNotFound extends LoadingError + + implicit val show: Show[LoadingError] = Show.show { + case IndexNotFound => "cannot find ReadonlyREST settings index" + case DocumentNotFound => "cannot found document with ReadonlyREST settings" + } } type IndexSettingsSavingError = SavingSettingsError[SavingError] @@ -78,5 +84,9 @@ object IndexSettingsSource { sealed trait SavingError object SavingError { case object CannotSaveSettings extends SavingError + + implicit val show: Show[SavingError] = Show.show { + case CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" + } } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala index 521ec6a561..0e28e099f3 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala @@ -18,17 +18,18 @@ package tech.beshu.ror.settings.source import io.circe.Decoder import tech.beshu.ror.accesscontrol.domain.RorSettingsFile -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettingsYamlParser} class MainSettingsFileSource private (settingsFile: RorSettingsFile) - (implicit decoder: Decoder[RawRorSettings]) - extends FileSettingsSource[RawRorSettings](settingsFile.file) + (implicit decoder: Decoder[MainRorSettings]) + extends FileSettingsSource[MainRorSettings](settingsFile.file) object MainSettingsFileSource { def create(settingsFile: RorSettingsFile, settingsYamlParser: RawRorSettingsYamlParser): MainSettingsFileSource = { - implicit val decoder: Decoder[RawRorSettings] = new RawRorSettingsCodec(settingsYamlParser) + implicit val decoder: Decoder[MainRorSettings] = + new RawRorSettingsCodec(settingsYamlParser).map(MainRorSettings.apply) new MainSettingsFileSource(settingsFile) } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala index e83f170c9b..37a2258ed3 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala @@ -18,21 +18,21 @@ package tech.beshu.ror.settings.source import io.circe.Codec import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.es.IndexDocumentReader import tech.beshu.ror.settings.source.MainSettingsIndexSource.Const class MainSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, settingsIndex: RorSettingsIndex) - (implicit codec: Codec[RawRorSettings]) - extends IndexSettingsSource[RawRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) + (implicit codec: Codec[MainRorSettings]) + extends IndexSettingsSource[MainRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) object MainSettingsIndexSource { def create(indexJsonContentService: IndexDocumentReader, settingsIndex: RorSettingsIndex, settingsYamlParser: RawRorSettingsYamlParser): MainSettingsIndexSource = { - implicit val codec: Codec[RawRorSettings] = new RawRorSettingsCodec(settingsYamlParser) + implicit val codec: Codec[MainRorSettings] = mainRorSettingsCodec(settingsYamlParser) new MainSettingsIndexSource(indexJsonContentService, settingsIndex) } @@ -40,4 +40,9 @@ object MainSettingsIndexSource { val id = "1" val settingsKey = "settings" } + + private def mainRorSettingsCodec(settingsYamlParser: RawRorSettingsYamlParser): Codec[MainRorSettings] = { + implicit val codec: Codec[RawRorSettings] = new RawRorSettingsCodec(settingsYamlParser) + Codec.forProduct1[MainRorSettings, RawRorSettings](Const.settingsKey)(MainRorSettings.apply)(_.rawSettings) + } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala index ff115e0817..e57dc16213 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.settings.source +import cats.implicits.* import io.circe.Decoder.Result import io.circe.{Codec, Decoder, HCursor, Json} import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} @@ -29,7 +30,7 @@ private [source] class RawRorSettingsCodec(yamlParser: RawRorSettingsYamlParser) .emap { str => yamlParser .fromString(str) - .left.map { _ => ??? } + .left.map(_.show) } .apply(c) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 378ef2d533..14bbcd2c45 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.settings.source +import cats.Show import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError @@ -23,7 +24,7 @@ import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsErro sealed trait SettingsSource[SETTINGS] -trait ReadOnlySettingsSource[SETTINGS : Decoder, ERROR] extends SettingsSource[SETTINGS] { +trait ReadOnlySettingsSource[SETTINGS: Decoder, ERROR] extends SettingsSource[SETTINGS] { def load(): Task[Either[LoadingSettingsError[ERROR], SETTINGS]] } object ReadOnlySettingsSource { @@ -33,10 +34,13 @@ object ReadOnlySettingsSource { final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError[ERROR] } - //implicit val show: Show[LoadingSettingsError[_]] = ??? + implicit def show[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { + case LoadingSettingsError.SettingsMalformed(cause) => "settings taken from index's document is malformed" + case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + } } -trait ReadWriteSettingsSource[SETTINGS : Encoder : Decoder, READ_SPECIFIC_ERROR, WRITE_SPECIFIC_ERROR] +trait ReadWriteSettingsSource[SETTINGS: Encoder : Decoder, READ_SPECIFIC_ERROR, WRITE_SPECIFIC_ERROR] extends ReadOnlySettingsSource[SETTINGS, READ_SPECIFIC_ERROR] { def save(settings: SETTINGS): Task[Either[SavingSettingsError[WRITE_SPECIFIC_ERROR], Unit]] @@ -47,5 +51,7 @@ object ReadWriteSettingsSource { final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError[ERROR] } - // implicit val show: Show[SavingSettingsError] = ??? + implicit def show[ERROR: Show]: Show[SavingSettingsError[ERROR]] = Show.show { + case SavingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala index 155b08a630..f3a6909528 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala @@ -35,10 +35,10 @@ import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.json.KeyCodec -import java.time.{Instant, ZoneOffset} import java.time.format.DateTimeFormatter +import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration -import scala.util.{Failure, Success, Try} +import scala.util.Try class TestSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, settingsIndex: RorSettingsIndex) @@ -170,27 +170,22 @@ object TestSettingsIndexSource { } private implicit lazy val expirationTtlDecoder: Codec[PositiveFiniteDuration] = { - val decoder = Decoder.decodeString.map { str => - Try { - Duration(str.toLong, "ms").toRefinedPositive match { - case Right(value) => value - case Left(errorMsg) => ??? - } - } match { - case Success(value) => value - case Failure(exception) => ??? - } + val decoder = Decoder.decodeString.emap { str => + for { + duration <- Try(Duration(str.toLong, "ms")).toEither.left.map(_ => s"Cannot create decode string '$str' to duration") + positiveFiniteDuration <- duration.toRefinedPositive + } yield positiveFiniteDuration } val encoder: Encoder[PositiveFiniteDuration] = Encoder.encodeString.contramap(_.value.toMillis.toString) Codec.from(decoder, encoder) } private implicit lazy val expirationTimeDecoder: Decoder[Instant] = { - val decoder = Decoder.decodeString.map { str => - Try(DateTimeFormatter.ISO_DATE_TIME.parse(str)).map(Instant.from) match { - case Success(value) => value - case Failure(exception) => ??? - } + val decoder = Decoder.decodeString.emap { str => + Try(DateTimeFormatter.ISO_DATE_TIME.parse(str)) + .map(Instant.from) + .toEither + .left.map(_ => s"Cannot decode string 'str' to date") } val encoder: Encoder[Instant] = Encoder.encodeString.contramap(_.atOffset(ZoneOffset.UTC).toString) Codec.from(decoder, encoder) diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala index c4aea7d447..0036bc3be2 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala @@ -20,35 +20,27 @@ import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.FileSettingsSource -import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError import tech.beshu.ror.utils.ScalaOps.* -class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSource[RawRorSettings]) +class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSource[MainRorSettings]) extends StartingRorSettingsLoader with Logging { - override def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { + override def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] = { val result = for { - _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${mainSettingsFileSource.settingsFile.show}")) + _ <- lift(logger.info(s"Loading ReadonlyREST main settings from file: ${mainSettingsFileSource.settingsFile.show}")) settings <- EitherT(mainSettingsFileSource.load()) - .leftMap(convertFileError) - .leftSemiflatTap { error => - logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") - } + .biSemiflatTap( + error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.toString}"), + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file: ${settings.rawSettings.raw.show}") + ) + .leftMap(error => StartingFailure(error.show)) } yield (settings, None) result.value } - private def convertFileError(error: FileSettingsLoadingError): StartingFailure = { - ??? - // error match { - // case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) - // case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) - // } - } - private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala index b1c5694520..4ad8124f39 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -20,12 +20,9 @@ import cats.data.EitherT import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.source.* -import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError -import tech.beshu.ror.settings.source.IndexSettingsSource.IndexSettingsLoadingError -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.utils.ScalaOps.* class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource: MainSettingsIndexSource, @@ -34,7 +31,7 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn /* todo: retry strategy*/) extends StartingRorSettingsLoader with Logging { - override def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] = { + override def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] = { loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()).value val result = for { mainSettings <- loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()) @@ -50,105 +47,37 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn _ <- lift(logger.info(s"Loading ReadonlyREST main settings from index (${mainSettingsIndexSource.settingsIndex.show}) ...")) loadedSettings <- EitherT(mainSettingsIndexSource.load()) .biSemiflatTap( - error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: "), // todo: ${error.show}") - // todo: - // case LoadingFromIndexError.IndexParsingError(message) => - // logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") - // case LoadingFromIndexError.IndexUnknownStructure => - // logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") - // case LoadingFromIndexError.IndexNotExist => - // logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.raw.show}") + error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: ${error.show}"), + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.rawSettings.raw.show}") ) - .leftMap(convertIndexError) + .leftMap(error => StartingFailure(error.show)) } yield loadedSettings } - private def convertIndexError(error: IndexSettingsLoadingError): StartingFailure = error match { - case LoadingSettingsError.SettingsMalformed(_) => ??? - case LoadingSettingsError.SourceSpecificError(IndexSettingsSource.LoadingError.IndexNotFound) => ??? - case LoadingSettingsError.SourceSpecificError(IndexSettingsSource.LoadingError.DocumentNotFound) => ??? - } - private def loadMainSettingsFromFile() = { for { - _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${mainSettingsFileSource.settingsFile.show}")) + _ <- lift(logger.info(s"Loading ReadonlyREST main settings from file: ${mainSettingsFileSource.settingsFile.show}")) loadedSettings <- EitherT(mainSettingsFileSource.load()) .biSemiflatTap( - error => logger.dError(s"Loading ReadonlyREST settings from file failed:"), // todo: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST settings from index: ${settings.raw.show}") + error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.rawSettings.raw.show}") ) - .leftMap(convertFileError) + .leftMap(error => StartingFailure(error.show)) } yield loadedSettings } - private def convertFileError(error: FileSettingsLoadingError): StartingFailure = error match { - case LoadingSettingsError.SettingsMalformed(_) => ??? - case LoadingSettingsError.SourceSpecificError(FileSettingsSource.LoadingError.FileNotExist(_)) => ??? - } - private def loadTestSettingsFromIndex() = { for { _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${testSettingsIndexSource.settingsIndex.show}) ...")) loadedSettings <- EitherT(testSettingsIndexSource.load()) .biSemiflatTap( - error => logger.dInfo(s"Loading ReadonlyREST test settings from index failed: "), // todo: ${error.show}") - // todo: - // case LoadingFromIndexError.IndexParsingError(message) => - // logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") - // case LoadingFromIndexError.IndexUnknownStructure => - // logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") - // case LoadingFromIndexError.IndexNotExist => - // logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") + error => logger.dInfo(s"Loading ReadonlyREST test settings from index failed: ${error.show}"), settings => logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${settings.rawSettings.raw.show}") ) - .leftMap(convertIndexError) + .leftMap(error => StartingFailure(error.show)) .map(Option(_)) } yield loadedSettings } private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) - - // private def toStartingFailure(error: LoadingError) = { - // error match { - // case Left(LoadingSettingsError.FormatError) => - // StartingFailure(???) - // case Right(LoadingSettingsError.FormatError) => - // StartingFailure(???) - // // case Left(LoadingSettingsError.FileParsingError(message)) => - // // StartingFailure(message) - // // case Left(LoadingFromFileError.FileNotExist(file)) => - // // StartingFailure(s"Cannot find settings file: ${file.show}") - // // case Right(LoadingFromIndexError.IndexParsingError(message)) => - // // StartingFailure(message) - // // case Right(LoadingFromIndexError.IndexUnknownStructure) => - // // StartingFailure(s"Settings index is malformed") - // // case Right(LoadingFromIndexError.IndexNotExist) => - // // StartingFailure(s"Settings index doesn't exist") - // } - // } - // - // private def loadTestSettings(esConfigBasedRorSettings: EsConfigBasedRorSettings, - // indexSettingsSource: IndexSettingsSource[TestRorSettings]): EitherT[Task, StartingFailure, TestRorSettings] = { - // esConfig.loadingRorCoreStrategy match { - // case LoadingRorCoreStrategy.ForceLoadingFromFile(_) => - // EitherT.rightT[Task, StartingFailure](TestRorSettings.NotSet) - // case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, _) => - // EitherT(new TestSettingsIndexOnlyLoadingStrategy(indexSettingsSource).load()) - // .leftFlatMap { - // case LoadingSettingsError.FormatError => ??? - // // todo: - // // case LoadingFromIndexError.IndexParsingError(message) => - // // logger.error(s"Loading ReadonlyREST test settings from index failed: ${message.show}. No test settings will be loaded.") - // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - // // case LoadingFromIndexError.IndexUnknownStructure => - // // logger.error("Loading ReadonlyREST test settings from index failed: index content malformed. No test settings will be loaded.") - // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - // // case LoadingFromIndexError.IndexNotExist => - // // logger.info("Loading ReadonlyREST test settings from index failed: cannot find index. No test settings will be loaded.") - // // EitherT.rightT[Task, StartingFailure](notSetTestRorSettings) - // } - // } - // } - } diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala index ef124c07f9..97c91f10c7 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala @@ -18,9 +18,9 @@ package tech.beshu.ror.settings.strategy import monix.eval.Task import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{RawRorSettings, TestRorSettings} +import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} trait StartingRorSettingsLoader { - def load(): Task[Either[StartingFailure, (RawRorSettings, Option[TestRorSettings])]] + def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] } From c78b1e33906cdbcfe286507884c98f9307a4756c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Sep 2025 11:58:53 +0200 Subject: [PATCH 032/103] wip --- .../unit/boot/ReadonlyRestStartingTests.scala | 321 +++++++++--------- 1 file changed, 160 insertions(+), 161 deletions(-) diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 507d422486..c6ea8fb8fe 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -48,10 +48,9 @@ import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.configuration.manager.InIndexSettingsManager.SavingIndexSettingsError import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} -import tech.beshu.ror.es.IndexDocumentReader.{CannotReachContentSource, CannotWriteToIndex, DocumentNotFound, WriteError} +import tech.beshu.ror.es.IndexDocumentReader.{CannotWriteToIndex, DocumentNotFound, IndexNotFound, WriteError} import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentReader} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -77,27 +76,27 @@ class ReadonlyRestStartingTests "support the main engine" should { "be loaded from file" when { "index is not available but file config is provided" in withReadonlyRest({ - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - (mockedIndexJsonContentManager.sourceOf _) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) - .returns(Task.now(Left(CannotReachContentSource))) + .returns(Task.now(Left(IndexNotFound))) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockCoreFactory(mock[CoreFactory], "/boot_tests/no_index_config_file_config_provided/readonlyrest.yml") - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, "/boot_tests/no_index_config_file_config_provided/") + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/no_index_config_file_config_provided/") }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] acl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "file loading is forced in elasticsearch.yml" in withReadonlyRest({ - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading/readonlyrest.yml") - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, "/boot_tests/forced_file_loading/") + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/forced_file_loading/") }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -109,12 +108,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -124,13 +123,13 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -143,16 +142,16 @@ class ReadonlyRestStartingTests val initialIndexConfigFile = "readonlyrest_initial.yml" val newIndexConfigFile = "readonlyrest_first.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + initialIndexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + initialIndexConfigFile) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + initialIndexConfigFile) mockCoreFactory(coreFactory, resourcesPath + newIndexConfigFile) - mockIndexJsonContentManagerSaveCall(mockedIndexJsonContentManager, resourcesPath + newIndexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + mockIndexJsonContentManagerSaveCall(mockedIndexDocumentReader, resourcesPath + newIndexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(0 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) }) { rorInstance => val mainEngine = rorInstance.engines.value.mainEngine mainEngine.core.accessControl shouldBe a[AccessControlListLoggingDecorator] @@ -171,9 +170,9 @@ class ReadonlyRestStartingTests val firstNewIndexConfigFile = "readonlyrest_first.yml" val secondNewIndexConfigFile = "readonlyrest_second.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + initialIndexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + initialIndexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + initialIndexConfigFile) @@ -185,14 +184,14 @@ class ReadonlyRestStartingTests .map(_ => Right(Core(mockEnabledAccessControl, RorDependencies.noOp, None))) // very long creation ) mockIndexJsonContentManagerSaveCall( - mockedIndexJsonContentManager, + mockedIndexDocumentReader, resourcesPath + firstNewIndexConfigFile, Task.sleep(500 millis).map(_ => Right(())) // very long saving ) - val readonlyrest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(0 seconds)) - (readonlyrest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyrest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) + (readonlyrest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => val resourcesPath = "/boot_tests/config_reloading/" val firstNewIndexConfigFile = "readonlyrest_first.yml" val secondNewIndexConfigFile = "readonlyrest_second.yml" @@ -207,7 +206,7 @@ class ReadonlyRestStartingTests .forceReloadAndSave(rorConfigFromResource(resourcesPath + firstNewIndexConfigFile))(newRequestId()) .map { result => // schedule after first finish - mockIndexJsonContentManagerSaveCall(mockedIndexJsonContentManager, resourcesPath + secondNewIndexConfigFile) + mockIndexJsonContentManagerSaveCall(mockedIndexDocumentReader, resourcesPath + secondNewIndexConfigFile) result }, Task @@ -227,17 +226,17 @@ class ReadonlyRestStartingTests val originIndexConfigFile = "readonlyrest.yml" val updatedIndexConfigFile = "updated_readonlyrest.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] + val mockedIndexDocumentReader = mock[IndexDocumentReader] val coreFactory = mock[CoreFactory] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + originIndexConfigFile, repeatedCount = 1) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + originIndexConfigFile, repeatedCount = 1) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) mockCoreFactory(coreFactory, resourcesPath + originIndexConfigFile, mockDisabledAccessControl) - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + updatedIndexConfigFile) + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + updatedIndexConfigFile) mockCoreFactory(coreFactory, resourcesPath + updatedIndexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -276,13 +275,13 @@ class ReadonlyRestStartingTests } } "index config doesn't exist and file config is malformed" in { - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - (mockedIndexJsonContentManager.sourceOf _) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexJsonContentManager, "/boot_tests/index_config_not_exists_malformed_file_config/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentReader, "/boot_tests/index_config_not_exists_malformed_file_config/") val result = readonlyRest.start().runSyncUnsafe() @@ -291,15 +290,15 @@ class ReadonlyRestStartingTests } } "index config doesn't exist and file config cannot be loaded" in { - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - (mockedIndexJsonContentManager.sourceOf _) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml") - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, "/boot_tests/index_config_not_exists_bad_file_config/") + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/index_config_not_exists_bad_file_config/") val result = readonlyRest.start().runSyncUnsafe() @@ -311,11 +310,11 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/malformed_index_config/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexJsonContentManager, resourcesPath) + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentReader, resourcesPath) val result = readonlyRest.start().runSyncUnsafe() @@ -327,12 +326,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/bad_index_config/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath) + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) val result = readonlyRest.start().runSyncUnsafe() @@ -375,10 +374,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -386,7 +385,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(5 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -398,11 +397,11 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -418,7 +417,7 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) (readonlyRest, expirationTimestamp) }) { case (rorInstance, expirationTimestamp) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] @@ -461,11 +460,11 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().minusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -480,7 +479,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -498,10 +497,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(CannotReachContentSource))) @@ -509,7 +508,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(5 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -521,11 +520,11 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().minusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -540,7 +539,7 @@ class ReadonlyRestStartingTests val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(5 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -552,10 +551,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -571,7 +570,7 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockFailedCoreFactory(coreFactory, testConfigMalformed) - readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(5 seconds)) + readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( @@ -588,10 +587,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -600,14 +599,14 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -640,10 +639,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -652,13 +651,13 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -709,10 +708,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -721,13 +720,13 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -756,7 +755,7 @@ class ReadonlyRestStartingTests val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -792,10 +791,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -805,13 +804,13 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) mockCoreFactory(coreFactory, testConfig2, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -841,7 +840,7 @@ class ReadonlyRestStartingTests val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -878,10 +877,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -890,12 +889,12 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -927,12 +926,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -948,9 +947,9 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) + (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) + }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, @@ -961,7 +960,7 @@ class ReadonlyRestStartingTests ) val expirationTimestamp2 = testClock.instant().plusSeconds(200) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -990,12 +989,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -1011,9 +1010,9 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) + (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) + }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( @@ -1025,7 +1024,7 @@ class ReadonlyRestStartingTests ) val expirationTimestamp2 = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -1054,12 +1053,12 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile, 2) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -1075,9 +1074,9 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) + (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) + }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( @@ -1089,7 +1088,7 @@ class ReadonlyRestStartingTests ) val expirationTimestamp2 = testClock.instant().minusSeconds(1) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -1118,9 +1117,9 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -1129,14 +1128,14 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(0 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -1170,10 +1169,10 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Left(DocumentNotFound))) @@ -1182,13 +1181,13 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexJsonContentManager) - }) { case (rorInstance, mockedIndexJsonContentManager) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, mockedIndexDocumentReader) + }) { case (rorInstance, mockedIndexDocumentReader) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -1211,7 +1210,7 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() shouldBe a[TestSettings.Present] - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -1238,11 +1237,11 @@ class ReadonlyRestStartingTests val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" val indexConfigFile = "readonlyrest_index.yml" - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexJsonContentManager, resourcesPath + indexConfigFile) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexJsonContentManager.sourceOf _) + (mockedIndexDocumentReader.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) .returns(Task.now(Right( @@ -1258,9 +1257,9 @@ class ReadonlyRestStartingTests mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexJsonContentManager, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, (mockedIndexJsonContentManager, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexJsonContentManager, expirationTimestamp)) => + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) + }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( @@ -1271,7 +1270,7 @@ class ReadonlyRestStartingTests ) ) - (mockedIndexJsonContentManager.saveContent _) + (mockedIndexDocumentReader.saveDocumentJson _) .expects( where { (config: IndexName.Full, id: String, content: Map[String, String]) => @@ -1313,8 +1312,8 @@ class ReadonlyRestStartingTests } } "unable to setup data stream audit output" in { - val mockedIndexJsonContentManager = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexJsonContentManager) + val mockedIndexDocumentReader = mock[IndexDocumentReader] + mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) val dataStreamSinkConfig1 = AuditSink.Config.EsDataStreamBasedSink.default val dataStreamSinkConfig2 = dataStreamSinkConfig1.copy( @@ -1351,7 +1350,7 @@ class ReadonlyRestStartingTests val readonlyRest = readonlyRestBoot( coreFactory, - mockedIndexJsonContentManager, + mockedIndexDocumentReader, "/boot_tests/forced_file_loading_with_audit/", auditSinkServiceCreator ) @@ -1433,7 +1432,7 @@ class ReadonlyRestStartingTests private def mockIndexJsonContentManagerSourceOfCall(mockedManager: IndexDocumentReader, resourceFileName: String, repeatedCount: Int = 1) = { - (mockedManager.sourceOf _) + (mockedManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "1") .repeated(repeatedCount) .returns(Task.now(Right( @@ -1443,7 +1442,7 @@ class ReadonlyRestStartingTests } private def mockIndexJsonContentManagerSourceOfCallTestConfig(mockedManager: IndexDocumentReader) = { - (mockedManager.sourceOf _) + (mockedManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .anyNumberOfTimes() .returns(Task.now(Left(DocumentNotFound))) @@ -1453,7 +1452,7 @@ class ReadonlyRestStartingTests private def mockIndexJsonContentManagerSaveCall(mockedManager: IndexDocumentReader, resourceFileName: String, saveResult: Task[Either[WriteError, Unit]] = Task.now(Right(()))) = { - (mockedManager.saveContent _) + (mockedManager.saveDocumentJson _) .expects(fullIndexName(".readonlyrest"), "1", Map("settings" -> getResourceContent(resourceFileName))) .once() .returns(saveResult) From 9f6b4ce45b4aa3c2759bcc48842115052c1debb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Sep 2025 15:34:15 +0200 Subject: [PATCH 033/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 26 +- .../SettingsRelatedCreatorsAndLoaders.scala | 19 +- ...eader.scala => IndexDocumentManager.scala} | 6 +- .../ForceLoadRorSettingsFromFileLoader.scala | 4 +- .../ror/settings/loader/RetryStrategy.scala | 68 + ...hFileSourceFallbackRorSettingsLoader.scala | 18 +- .../StartingRorSettingsLoader.scala | 2 +- .../settings/source/FileSettingsSource.scala | 11 +- .../settings/source/IndexSettingsSource.scala | 16 +- .../source/MainSettingsIndexSource.scala | 8 +- .../ror/settings/source/SettingsSource.scala | 2 +- .../source/TestSettingsIndexSource.scala | 10 +- .../config_reloading/readonlyrest.yml | 4 + .../config_reloading/readonlyrest_first.yml | 7 +- .../config_reloading/readonlyrest_initial.yml | 7 +- .../config_reloading/readonlyrest_second.yml | 6 +- .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 1 - .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../forced_file_loading/readonlyrest.yml | 9 +- .../readonlyrest.yml | 3 +- .../custom_index_defined/readonlyrest.yml | 1 - .../no_index_defined/readonlyrest.yml | 1 - .../readonlyrest.yml | 9 +- .../readonlyrest_index.yml | 9 +- .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../readonlyrest.yml | 6 + .../malformed_index_config/readonlyrest.yml | 8 + .../no_es_api_ssl_settings/readonlyrest.yml | 6 + .../readonlyrest.yml | 9 +- .../readonlyrest.yml | 6 + .../ActionYamlLoadedAccessControlTest.scala | 2 +- .../integration/AuditOutputFormatTests.scala | 2 +- .../BaseYamlLoadedAccessControlTest.scala | 38 +- ...roupsWithProxyAuthAccessControlTests.scala | 2 +- ...rrentGroupHandlingAccessControlTests.scala | 2 +- ...urrentUserMetadataAccessControlTests.scala | 2 +- .../GroupsRuleAccessControlTests.scala | 2 +- .../IndicesYamlLoadedAccessControlTests.scala | 2 +- ...ndAccessYamlLoadedAccessControlTests.scala | 2 +- ...ityCheckYamlLoadedAccessControlTests.scala | 2 +- ...eryCheckYamlLoadedAccessControlTests.scala | 2 +- .../RegularRequestAccessControlTests.scala | 2 +- ...rKbnAuthYamlLoadedAccessControlTests.scala | 6 +- ...esolvingYamlLoadedAccessControlTests.scala | 2 +- .../unit/acl/factory/AuditSettingsTests.scala | 322 ++-- .../unit/acl/factory/CoreFactoryTests.scala | 97 +- .../factory/ImpersonationWarningsTests.scala | 59 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 55 +- .../rules/BaseRuleSettingsDecoderTest.scala | 8 +- .../unit/boot/ReadonlyRestStartingTests.scala | 1483 +++++++++-------- .../beshu/ror/unit/boot/RorIndexTest.scala | 251 ++- .../LoadRawRorSettingsTest.scala | 158 -- .../configuration/RorBootSettingsTest.scala | 50 +- .../configuration/SslConfigurationTest.scala | 145 +- .../YamlFileBasedRorSettingsLoaderTest.scala | 5 +- .../ror/unit/utils/RorYamlParserTests.scala | 16 +- .../tech/beshu/ror/utils/TestsUtils.scala | 18 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 4 +- ...der.scala => EsIndexDocumentManager.scala} | 10 +- 67 files changed, 1592 insertions(+), 1499 deletions(-) rename core/src/main/scala/tech/beshu/ror/es/{IndexDocumentReader.scala => IndexDocumentManager.scala} (90%) rename core/src/main/scala/tech/beshu/ror/settings/{strategy => loader}/ForceLoadRorSettingsFromFileLoader.scala (95%) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala rename core/src/main/scala/tech/beshu/ror/settings/{strategy => loader}/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala (87%) rename core/src/main/scala/tech/beshu/ror/settings/{strategy => loader}/StartingRorSettingsLoader.scala (96%) create mode 100644 core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml create mode 100644 core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml delete mode 100644 core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala rename es90x/src/main/scala/tech/beshu/ror/es/services/{EsIndexDocumentReader.scala => EsIndexDocumentManager.scala} (94%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 0e84633414..36696058b0 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.boot +import cats.Show import cats.data.{EitherT, NonEmptyList} import monix.eval.Task import monix.execution.Scheduler @@ -34,16 +35,15 @@ import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, Core import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* import tech.beshu.ror.configuration.* -import tech.beshu.ror.es.{EsEnv, IndexDocumentReader} +import tech.beshu.ror.es.{EsEnv, IndexDocumentManager} import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant class ReadonlyRest(coreFactory: CoreFactory, - indexContentService: IndexDocumentReader, - auditSinkServiceCreator: AuditSinkServiceCreator, - val esEnv: EsEnv) + indexDocumentManager: IndexDocumentManager, + auditSinkServiceCreator: AuditSinkServiceCreator) (implicit systemContext: SystemContext, scheduler: Scheduler) extends Logging { @@ -52,7 +52,7 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfigBasedRorSettings: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { - creatorsAndLoaders <- lift(SettingsRelatedCreatorsAndLoaders.create(esConfigBasedRorSettings, indexContentService)) + creatorsAndLoaders <- lift(SettingsRelatedCreatorsAndLoaders.create(esConfigBasedRorSettings, indexDocumentManager)) loadedSettings <- EitherT(creatorsAndLoaders.startingRorSettingsLoader.load()) (loadedMainRorSettings, loadedTestRorSettings) = loadedSettings instance <- startRor(esConfigBasedRorSettings, creatorsAndLoaders.creators, loadedMainRorSettings, loadedTestRorSettings) @@ -206,6 +206,10 @@ object ReadonlyRest { // todo: move somewhere else final case class StartingFailure(message: String, throwable: Option[Throwable] = None) + object StartingFailure { + // todo: move? + implicit val show: Show[StartingFailure] = Show.show(_.message) + } final case class MainEngine(engine: Engine, settings: RawRorSettings) @@ -238,21 +242,21 @@ object ReadonlyRest { } } - def create(indexContentService: IndexDocumentReader, + // todo: do we need both? + def create(indexContentService: IndexDocumentManager, auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) (implicit scheduler: Scheduler, systemContext: SystemContext): ReadonlyRest = { val coreFactory: CoreFactory = new RawRorSettingsBasedCoreFactory(env.esVersion) - create(coreFactory, indexContentService, auditSinkServiceCreator, env) + create(coreFactory, indexContentService, auditSinkServiceCreator) } def create(coreFactory: CoreFactory, - indexContentService: IndexDocumentReader, - auditSinkServiceCreator: AuditSinkServiceCreator, - env: EsEnv) + indexDocumentManager: IndexDocumentManager, + auditSinkServiceCreator: AuditSinkServiceCreator) (implicit scheduler: Scheduler, systemContext: SystemContext): ReadonlyRest = { - new ReadonlyRest(coreFactory, indexContentService, auditSinkServiceCreator, env) + new ReadonlyRest(coreFactory, indexDocumentManager, auditSinkServiceCreator) } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index 4b49f9ff99..a6915304b1 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -20,9 +20,9 @@ import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.es.IndexDocumentManager import tech.beshu.ror.settings.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} -import tech.beshu.ror.settings.strategy.{ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} +import tech.beshu.ror.settings.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} final class SettingsRelatedCreatorsAndLoaders private(val startingRorSettingsLoader: StartingRorSettingsLoader, val creators: SettingsRelatedCreators) @@ -35,22 +35,27 @@ final class SettingsRelatedCreators(val mainSettingsBasedReloadableEngineCreator object SettingsRelatedCreatorsAndLoaders { def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, - indexJsonContentService: IndexDocumentReader): SettingsRelatedCreatorsAndLoaders = { + indexDocumentManager: IndexDocumentManager): SettingsRelatedCreatorsAndLoaders = { val settingsYamlParser = new RawRorSettingsYamlParser(esConfigBasedRorSettings.settingsMaxSize) val mainSettingsIndexSource = MainSettingsIndexSource.create( - indexJsonContentService, esConfigBasedRorSettings.settingsIndex, settingsYamlParser + indexDocumentManager, esConfigBasedRorSettings.settingsIndex, settingsYamlParser ) val mainSettingsFileSource = MainSettingsFileSource.create( esConfigBasedRorSettings.settingsFile, settingsYamlParser ) val testSettingsIndexSource = TestSettingsIndexSource.create( - indexJsonContentService, esConfigBasedRorSettings.settingsIndex, settingsYamlParser + indexDocumentManager, esConfigBasedRorSettings.settingsIndex, settingsYamlParser ) val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { case s@LoadingRorCoreStrategy.ForceLoadingFromFile => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) - case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_) => - new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource, mainSettingsFileSource, testSettingsIndexSource) + case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(params) => + new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader( + mainSettingsIndexSource, + new ConfigurableRetryStrategy(params), + mainSettingsFileSource, + testSettingsIndexSource + ) } new SettingsRelatedCreatorsAndLoaders( startingSettingsLoader, diff --git a/core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala b/core/src/main/scala/tech/beshu/ror/es/IndexDocumentManager.scala similarity index 90% rename from core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala rename to core/src/main/scala/tech/beshu/ror/es/IndexDocumentManager.scala index c0533d2ce5..abcf9d99cf 100644 --- a/core/src/main/scala/tech/beshu/ror/es/IndexDocumentReader.scala +++ b/core/src/main/scala/tech/beshu/ror/es/IndexDocumentManager.scala @@ -19,14 +19,14 @@ package tech.beshu.ror.es import io.circe.Json import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.es.IndexDocumentReader.{ReadError, WriteError} +import tech.beshu.ror.es.IndexDocumentManager.{ReadError, WriteError} -trait IndexDocumentReader { +trait IndexDocumentManager { def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] } -object IndexDocumentReader { +object IndexDocumentManager { sealed trait ReadError case object IndexNotFound extends ReadError diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala similarity index 95% rename from core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala rename to core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala index 0036bc3be2..a4e6bdf39f 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/ForceLoadRorSettingsFromFileLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.strategy +package tech.beshu.ror.settings.loader import cats.data.EitherT import monix.eval.Task @@ -33,7 +33,7 @@ class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSou _ <- lift(logger.info(s"Loading ReadonlyREST main settings from file: ${mainSettingsFileSource.settingsFile.show}")) settings <- EitherT(mainSettingsFileSource.load()) .biSemiflatTap( - error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.toString}"), + error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file: ${settings.rawSettings.raw.show}") ) .leftMap(error => StartingFailure(error.show)) diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala new file mode 100644 index 0000000000..ba2371897a --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala @@ -0,0 +1,68 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.loader + +import cats.Show +import cats.data.EitherT +import cats.implicits.toShow +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters + +trait RetryStrategy { + def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] + def withRetryT[ERROR: Show, RESULT](operation: EitherT[Task, ERROR, RESULT]): EitherT[Task, ERROR, RESULT] = + EitherT(withRetry(operation.value)) +} + +object NoRetryStrategy extends RetryStrategy { + override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] = + operation +} + +class ConfigurableRetryStrategy(params: LoadFromIndexParameters) // todo: custom case class + extends RetryStrategy with Logging { + + override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] = + attemptWithRetry(operation, currentAttempt = 1, params.loadingAttemptsCount.value.value) + + private def attemptWithRetry[ERROR : Show, A](operation: Task[Either[ERROR, A]], + currentAttempt: Int, + maxAttempts: Int): Task[Either[ERROR, A]] = { + val delay = if (currentAttempt == 1) params.loadingDelay.value.value else params.loadingAttemptsInterval.value.value + for { + _ <- Task.sleep(delay) + result <- operation + finalResult <- result match { + case Right(value) => + Task.now(Right(value)) + // todo: better mesages + case Left(error) if shouldRetry(currentAttempt, maxAttempts) => + logger.debug(s"Retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${params.loadingAttemptsInterval.show}...") + attemptWithRetry(operation, currentAttempt + 1, maxAttempts) + case Left(error) => + logger.debug(s"Operation failed after $currentAttempt attempts: ${error.show}") + Task.now(Left(error)) + } + } yield finalResult + } + + private def shouldRetry(currentAttempt: Int, maxAttempts: Int): Boolean = { + currentAttempt < maxAttempts + } + +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala similarity index 87% rename from core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala rename to core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala index 4ad8124f39..216300ba07 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.strategy +package tech.beshu.ror.settings.loader import cats.data.EitherT import monix.eval.Task @@ -26,29 +26,29 @@ import tech.beshu.ror.settings.source.* import tech.beshu.ror.utils.ScalaOps.* class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource: MainSettingsIndexSource, + mainSettingsIndexLadingRetryStrategy: RetryStrategy, mainSettingsFileSource: MainSettingsFileSource, - testSettingsIndexSource: TestSettingsIndexSource, - /* todo: retry strategy*/) + testSettingsIndexSource: TestSettingsIndexSource) extends StartingRorSettingsLoader with Logging { override def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] = { loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()).value val result = for { - mainSettings <- loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()) + mainSettings <- mainSettingsIndexLadingRetryStrategy + .withRetryT(loadMainSettingsFromIndex()) + .orElse(loadMainSettingsFromFile()) testSettings <- loadTestSettingsFromIndex().recover { case failure => Option.empty[TestRorSettings] } } yield (mainSettings, testSettings) result.value } - // todo: don't forget about porting this part of code: - // _ <- wait(parameters.loadingDelay.value.value) private def loadMainSettingsFromIndex() = { for { - _ <- lift(logger.info(s"Loading ReadonlyREST main settings from index (${mainSettingsIndexSource.settingsIndex.show}) ...")) + _ <- lift(logger.info(s"Loading ReadonlyREST main settings from index: ${mainSettingsIndexSource.settingsIndex.show} ...")) loadedSettings <- EitherT(mainSettingsIndexSource.load()) .biSemiflatTap( error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index:\n${settings.rawSettings.raw.show}") ) .leftMap(error => StartingFailure(error.show)) } yield loadedSettings @@ -60,7 +60,7 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn loadedSettings <- EitherT(mainSettingsFileSource.load()) .biSemiflatTap( error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index: ${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file:\n${settings.rawSettings.raw.show}") ) .leftMap(error => StartingFailure(error.show)) } yield loadedSettings diff --git a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala similarity index 96% rename from core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala rename to core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala index 97c91f10c7..2d6028b655 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/strategy/StartingRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.strategy +package tech.beshu.ror.settings.loader import monix.eval.Task import tech.beshu.ror.boot.ReadonlyRest.StartingFailure diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala index d1dc199fe3..be0ef89552 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.settings.source import better.files.File import cats.Show import cats.data.EitherT -import io.circe.{Decoder, DecodingFailure, ParsingFailure, parser} +import io.circe.{Decoder, Json} import monix.eval.Task import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist @@ -43,12 +43,9 @@ class FileSettingsSource[SETTINGS: Decoder](val settingsFile: File) EitherT .pure[Task, FileSettingsLoadingError](file.contentAsString) .subflatMap { raw => - parser - .decode(raw) - .left.map { - case ParsingFailure(message, _) => LoadingSettingsError.SettingsMalformed(message) - case failure: DecodingFailure => LoadingSettingsError.SettingsMalformed(failure.message) - } + Json + .fromString(raw).as[SETTINGS] + .left.map { failure => LoadingSettingsError.SettingsMalformed(failure.message) } } } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala index 3ffee05de4..05e24c5a6a 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala @@ -21,21 +21,21 @@ import io.circe.syntax.* import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.es.IndexDocumentReader -import tech.beshu.ror.es.IndexDocumentReader.CannotWriteToIndex +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.CannotWriteToIndex import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.{DocumentNotFound, IndexNotFound} import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.source.IndexSettingsSource.{IndexSettingsLoadingError, IndexSettingsSavingError, LoadingError, SavingError} import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError -class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexJsonContentService: IndexDocumentReader, +class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: IndexDocumentManager, val settingsIndex: IndexName.Full, documentId: String) extends ReadWriteSettingsSource[SETTINGS, LoadingError, SavingError] { override def load(): Task[Either[IndexSettingsLoadingError, SETTINGS]] = { - indexJsonContentService + indexDocumentManager .documentAsJson(settingsIndex, documentId) .map { case Right(document) => @@ -43,17 +43,17 @@ class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexJsonContentService: .left.map { decodingFailure => LoadingSettingsError.SettingsMalformed(decodingFailure.message) } - case Left(IndexDocumentReader.IndexNotFound) => + case Left(IndexDocumentManager.IndexNotFound) => settingsLoaderError(IndexNotFound) - case Left(IndexDocumentReader.DocumentNotFound) => + case Left(IndexDocumentManager.DocumentNotFound) => settingsLoaderError(DocumentNotFound) - case Left(IndexDocumentReader.DocumentUnreachable) => + case Left(IndexDocumentManager.DocumentUnreachable) => settingsLoaderError(IndexNotFound) // todo: throw ex? } } override def save(settings: SETTINGS): Task[Either[IndexSettingsSavingError, Unit]] = { - indexJsonContentService + indexDocumentManager .saveDocumentJson(settingsIndex, documentId, settings.asJson) .map { _.left.map { case CannotWriteToIndex => SavingSettingsError.SourceSpecificError(CannotSaveSettings) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala index 37a2258ed3..9c60a50ae6 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala @@ -19,17 +19,17 @@ package tech.beshu.ror.settings.source import io.circe.Codec import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.es.IndexDocumentManager import tech.beshu.ror.settings.source.MainSettingsIndexSource.Const -class MainSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, +class MainSettingsIndexSource private(indexDocumentManager: IndexDocumentManager, settingsIndex: RorSettingsIndex) (implicit codec: Codec[MainRorSettings]) - extends IndexSettingsSource[MainRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) + extends IndexSettingsSource[MainRorSettings](indexDocumentManager, settingsIndex.index, documentId = Const.id) object MainSettingsIndexSource { - def create(indexJsonContentService: IndexDocumentReader, + def create(indexJsonContentService: IndexDocumentManager, settingsIndex: RorSettingsIndex, settingsYamlParser: RawRorSettingsYamlParser): MainSettingsIndexSource = { implicit val codec: Codec[MainRorSettings] = mainRorSettingsCodec(settingsYamlParser) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 14bbcd2c45..083f485834 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -35,7 +35,7 @@ object ReadOnlySettingsSource { } implicit def show[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { - case LoadingSettingsError.SettingsMalformed(cause) => "settings taken from index's document is malformed" + case LoadingSettingsError.SettingsMalformed(cause) => "ROR settings are malformed" case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala index f3a6909528..7f9c63d495 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} import tech.beshu.ror.configuration.TestRorSettings.Expiration import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} -import tech.beshu.ror.es.IndexDocumentReader +import tech.beshu.ror.es.IndexDocumentManager import tech.beshu.ror.settings.source.TestSettingsIndexSource.Const import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* @@ -40,18 +40,18 @@ import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.Duration import scala.util.Try -class TestSettingsIndexSource private(indexJsonContentService: IndexDocumentReader, +class TestSettingsIndexSource private(indexDocumentManager: IndexDocumentManager, settingsIndex: RorSettingsIndex) (implicit codec: Codec[TestRorSettings]) - extends IndexSettingsSource[TestRorSettings](indexJsonContentService, settingsIndex.index, documentId = Const.id) + extends IndexSettingsSource[TestRorSettings](indexDocumentManager, settingsIndex.index, documentId = Const.id) object TestSettingsIndexSource { - def create(indexJsonContentService: IndexDocumentReader, + def create(indexDocumentManager: IndexDocumentManager, settingsIndex: RorSettingsIndex, settingsYamlParser: RawRorSettingsYamlParser): TestSettingsIndexSource = { implicit val codec: Codec[TestRorSettings] = createTestRorSettingsCodec(settingsYamlParser) - new TestSettingsIndexSource(indexJsonContentService, settingsIndex) + new TestSettingsIndexSource(indexDocumentManager, settingsIndex) } private object Const { diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml b/core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml new file mode 100644 index 0000000000..49b9cc0c4d --- /dev/null +++ b/core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml @@ -0,0 +1,4 @@ +readonlyrest: + access_control_rules: + - name: "Admin block" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml index 728b72e827..db6dd1ef47 100644 --- a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml +++ b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "INDEX MODIFIED: CONTAINER ADMIN" - verbosity: error - type: allow + - name: "INDEX MODIFIED: ADMIN" auth_key: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml index 20de7615cc..131501db46 100644 --- a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml +++ b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml @@ -1,11 +1,6 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "INDEX MODIFIED: CONTAINER ADMIN" - verbosity: error - type: allow + - name: "INDEX MODIFIED: ADMIN" auth_key: admin:container - name: "User 1" diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml index 25896ce915..1cfbcfea56 100644 --- a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml +++ b/core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml @@ -1,11 +1,7 @@ readonlyrest: - access_control_rules: - # ES container initializer need this rule to configure ES instance after startup - - name: "INDEX MODIFIED: CONTAINER ADMIN" - verbosity: error - type: allow + - name: "INDEX MODIFIED: ADMIN" auth_key: admin:container - name: "User 2" diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml index e31469bb3f..3e92390c77 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml @@ -10,7 +10,6 @@ readonlyrest: access_control_rules: - # ES container initializer need this rule to configure ES instance after startup - name: "CONTAINER ADMIN" verbosity: error type: allow diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml index 52df94de84..49b9cc0c4d 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "Admin block" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml index 78af795426..3815fac3ba 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml @@ -2,8 +2,7 @@ readonlyrest: access_control_rules: - # ES container initializer need this rule to configure ES instance after startup - name: "CONTAINER ADMIN" verbosity: error type: allow - auth_key: "admin:container \ No newline at end of file + auth_key_1: "admin:container" \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml index 52df94de84..0b14130e53 100644 --- a/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml @@ -2,7 +2,6 @@ readonlyrest: access_control_rules: - # ES container initializer need this rule to configure ES instance after startup - name: "CONTAINER ADMIN" verbosity: error type: allow diff --git a/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml index 52df94de84..0b14130e53 100644 --- a/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml @@ -2,7 +2,6 @@ readonlyrest: access_control_rules: - # ES container initializer need this rule to configure ES instance after startup - name: "CONTAINER ADMIN" verbosity: error type: allow diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml index 52df94de84..49b9cc0c4d 100644 --- a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "Admin block" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml index 728b72e827..db58e7b79a 100644 --- a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml +++ b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "INDEX MODIFIED: CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "INDEX MODIFIED: Admin block" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml new file mode 100644 index 0000000000..85a27f8fd6 --- /dev/null +++ b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml @@ -0,0 +1,8 @@ +readonlyrest: + + access_control_rules: + + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + auth_key: "admin:container" \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml b/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml index 52df94de84..49b9cc0c4d 100644 --- a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "Admin block" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml b/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml new file mode 100644 index 0000000000..61be106845 --- /dev/null +++ b/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml @@ -0,0 +1,6 @@ +readonlyrest: + access_control_rules: + - name: "CONTAINER ADMIN" + verbosity: error + type: allow + unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala index 86a4aae70b..cec26d3722 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala @@ -26,7 +26,7 @@ import tech.beshu.ror.mocks.MockRequestContext class ActionYamlLoadedAccessControlTest extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala b/core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala index fb3055f6e3..efc6ced919 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/AuditOutputFormatTests.scala @@ -42,7 +42,7 @@ import scala.language.postfixOps class AuditOutputFormatTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with MockFactory { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 909b599a9a..00aa1dcef3 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -18,12 +18,14 @@ package tech.beshu.ror.integration import cats.implicits.* import monix.execution.Scheduler.Implicits.global +import squants.information.Megabytes +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorSettingsBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.RawRorSettingsYamlParser import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.providers.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -31,13 +33,13 @@ import tech.beshu.ror.utils.TestsUtils.{BlockContextAssertion, defaultEsVersionF trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { - protected def configYaml: String + protected def settingsYaml: String protected implicit def envVarsProvider: EnvVarsProvider = OsEnvVarsProvider protected implicit def propertiesProvider: TestsPropertiesProvider = TestsPropertiesProvider.default - private implicit val systemContext: SystemContext = new Environment( + private implicit val systemContext: SystemContext = new SystemContext( envVarsProvider = envVarsProvider, propertiesProvider = propertiesProvider ) @@ -47,20 +49,20 @@ trait BaseYamlLoadedAccessControlTest extends BlockContextAssertion { protected val mockProvider: MocksProvider = NoOpMocksProvider lazy val acl: AccessControlList = { - val aclEngineT = for { - config <- RawRorSettings - .fromString(configYaml) - .map(_.fold(err => throw new IllegalStateException(err.show), identity)) - core <- factory - .createCoreFrom( - config, - RorSettingsIndex(IndexName.Full(".readonlyrest")), - httpClientsFactory, - ldapConnectionPoolProvider, - mockProvider - ) - .map(_.fold(err => throw new IllegalStateException(s"Cannot create ACL: $err"), identity)) - } yield core.accessControl - aclEngineT.runSyncUnsafe() + val yamlParser = new RawRorSettingsYamlParser(Megabytes(3)) + val rorSettings = yamlParser.fromString(settingsYaml) match { + case Right(value) => value + case Left(error) => throw new IllegalStateException(error.show) + } + factory + .createCoreFrom( + rorSettings, + RorSettingsIndex(IndexName.Full(".readonlyrest")), + httpClientsFactory, + ldapConnectionPoolProvider, + mockProvider + ) + .map(_.fold(err => throw new IllegalStateException(s"Cannot create ACL: $err"), _.accessControl)) + .runSyncUnsafe() } } diff --git a/core/src/test/scala/tech/beshu/ror/integration/CaseInsensitiveGroupsWithProxyAuthAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/CaseInsensitiveGroupsWithProxyAuthAccessControlTests.scala index d0b5f5f65e..fed2f83009 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/CaseInsensitiveGroupsWithProxyAuthAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/CaseInsensitiveGroupsWithProxyAuthAccessControlTests.scala @@ -30,7 +30,7 @@ import tech.beshu.ror.utils.uniquelist.UniqueList class CaseInsensitiveGroupsWithProxyAuthAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | global_settings: diff --git a/core/src/test/scala/tech/beshu/ror/integration/CurrentGroupHandlingAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/CurrentGroupHandlingAccessControlTests.scala index 995ff4e01b..608c7560cd 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/CurrentGroupHandlingAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/CurrentGroupHandlingAccessControlTests.scala @@ -38,7 +38,7 @@ class CurrentGroupHandlingAccessControlTests private val kbn1SignatureKey = "123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456" private val jwt1SignatureKey = "123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456.123456" - override protected def configYaml: String = + override protected def settingsYaml: String = s""" |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/CurrentUserMetadataAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/CurrentUserMetadataAccessControlTests.scala index fb53738631..8f90cc9eba 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/CurrentUserMetadataAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/CurrentUserMetadataAccessControlTests.scala @@ -72,7 +72,7 @@ class CurrentUserMetadataAccessControlTests override protected val httpClientsFactory: HttpClientsFactory = new AsyncHttpClientsFactory - override protected def configYaml: String = + override protected def settingsYaml: String = s""" |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/GroupsRuleAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/GroupsRuleAccessControlTests.scala index 9d34e9d488..cebd6596ec 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/GroupsRuleAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/GroupsRuleAccessControlTests.scala @@ -42,7 +42,7 @@ class GroupsRuleAccessControlTests override protected val ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider = new UnboundidLdapConnectionPoolProvider - override protected def configYaml: String = + override protected def settingsYaml: String = s""" |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/IndicesYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/IndicesYamlLoadedAccessControlTests.scala index 70a87ea548..e4a25f7d88 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/IndicesYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/IndicesYamlLoadedAccessControlTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.* class IndicesYamlLoadedAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/KibanaIndexAndAccessYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/KibanaIndexAndAccessYamlLoadedAccessControlTests.scala index 8cc3153a86..a7f5210512 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/KibanaIndexAndAccessYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/KibanaIndexAndAccessYamlLoadedAccessControlTests.scala @@ -36,7 +36,7 @@ class KibanaIndexAndAccessYamlLoadedAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/LdapConnectivityCheckYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/LdapConnectivityCheckYamlLoadedAccessControlTests.scala index a41a6c0ed2..b82db817c8 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/LdapConnectivityCheckYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/LdapConnectivityCheckYamlLoadedAccessControlTests.scala @@ -42,7 +42,7 @@ class LdapConnectivityCheckYamlLoadedAccessControlTests SingletonLdapContainers.ldap2 ) - override protected def configYaml: String = + override protected def settingsYaml: String = s"""readonlyrest: | | access_control_rules: diff --git a/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala index f7abc14cf2..0e434c4634 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala @@ -39,7 +39,7 @@ class LdapServerDiscoveryCheckYamlLoadedAccessControlTests override val container: LdapWithDnsContainer = new LdapWithDnsContainer("LDAP1", "test_example.ldif") - override protected def configYaml: String = + override protected def settingsYaml: String = s"""readonlyrest: | | access_control_rules: diff --git a/core/src/test/scala/tech/beshu/ror/integration/RegularRequestAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/RegularRequestAccessControlTests.scala index d0ca9e08f5..d8e75c34d9 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/RegularRequestAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/RegularRequestAccessControlTests.scala @@ -38,7 +38,7 @@ import java.util.Base64 class RegularRequestAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - protected def configYaml: String = + protected def settingsYaml: String = """ |other_non_ror_settings: | diff --git a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthYamlLoadedAccessControlTests.scala index dd4176cc32..ec8e90d0fd 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthYamlLoadedAccessControlTests.scala @@ -26,17 +26,17 @@ import tech.beshu.ror.accesscontrol.AccessControlList.RegularRequestResult import tech.beshu.ror.accesscontrol.blocks.Block import tech.beshu.ror.accesscontrol.domain.LoggedUser.DirectlyLoggedUser import tech.beshu.ror.accesscontrol.domain.{Jwt, User} -import tech.beshu.ror.mocks.{MockRequestContext, MockRestRequest} +import tech.beshu.ror.mocks.MockRequestContext +import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.TestsUtils.* import tech.beshu.ror.utils.uniquelist.UniqueList import scala.jdk.CollectionConverters.* -import tech.beshu.ror.syntax.* class RorKbnAuthYamlLoadedAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """http.bind_host: _eth0:ipv4_ |network.host: _eth0:ipv4_ | diff --git a/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala index ffac563b0f..f56e8159bb 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/VariableResolvingYamlLoadedAccessControlTests.scala @@ -55,7 +55,7 @@ class VariableResolvingYamlLoadedAccessControlTests extends AnyWordSpec private lazy val (pub, secret) = Random.generateRsaRandomKeys - override protected def configYaml: String = + override protected def settingsYaml: String = s""" |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index 3a015fc9a4..dfa7102c88 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -31,10 +31,10 @@ import tech.beshu.ror.accesscontrol.domain.AuditCluster.{LocalAuditCluster, Remo import tech.beshu.ror.accesscontrol.domain.{AuditCluster, IndexName, RorAuditLoggerName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.AuditingSettingsCreationError import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.{Core, RawRorSettingsBasedCoreFactory} +import tech.beshu.ror.accesscontrol.factory.{Core, RawRorSettingsBasedCoreFactory, RorDependencies} import tech.beshu.ror.audit.adapters.DeprecatedAuditLogSerializerAdapter import tech.beshu.ror.audit.instances.{DefaultAuditLogSerializer, QueryAuditLogSerializer} -import tech.beshu.ror.configuration.{RawRorSettings, RorDependencies} +import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.EsVersion import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.utils.TestsUtils.* @@ -54,7 +54,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { "Audit settings" when { "audit is not configured" should { "be disabled by default" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -66,13 +66,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { | """.stripMargin) - assertSettingsNoPresent(config) + assertSettingsNoPresent(settings) } } "audit is disabled" should { "be disabled" when { "one line audit format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit.enabled: false @@ -85,10 +85,10 @@ class AuditSettingsTests extends AnyWordSpec with Inside { | """.stripMargin) - assertSettingsNoPresent(config) + assertSettingsNoPresent(settings) } "multi line audit format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -102,16 +102,16 @@ class AuditSettingsTests extends AnyWordSpec with Inside { | """.stripMargin) - assertSettingsNoPresent(config) + assertSettingsNoPresent(settings) } } } "audit is enabled" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "no outputs defined" should { "fallback to default index based audit sink" when { "one line audit format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit.enabled: true @@ -125,13 +125,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "multi line audit format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -146,7 +146,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) @@ -154,7 +154,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } "simple format is used" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -171,14 +171,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(3) val sink1 = auditingSettings.auditSinks.head @@ -210,7 +210,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } "'log' output type defined" when { "only type is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -227,13 +227,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedLoggerName = "readonlyrest_audit" ) } "the output's enabled flag is set" when { "set to true" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -251,12 +251,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedLoggerName = "readonlyrest_audit" ) } "set to false" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -274,13 +274,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertSettings( - config, - expectedConfigs = NonEmptyList.of(AuditSink.Disabled) + settings, + expectedAuditSinks = NonEmptyList.of(AuditSink.Disabled) ) } } "custom logger name is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -298,12 +298,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedLoggerName = "custom_logger" ) } "custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -321,12 +321,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedLoggerName = "readonlyrest_audit" ) } "deprecated custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -344,12 +344,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[DeprecatedAuditLogSerializerAdapter[_]]( - config, + settings, expectedLoggerName = "readonlyrest_audit" ) } "all custom settings are set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -368,14 +368,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertLogBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedLoggerName = "custom_logger" ) } } "'index' output type defined" when { "only type is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -392,14 +392,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "the output's enabled flag is set" when { "set to true" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -417,13 +417,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "set to false" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -441,13 +441,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertSettings( - config, - expectedConfigs = NonEmptyList.of(AuditSink.Disabled) + settings, + expectedAuditSinks = NonEmptyList.of(AuditSink.Disabled) ) } } "custom audit index name is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -465,13 +465,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = LocalAuditCluster ) } "custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -489,13 +489,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "deprecated custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -513,13 +513,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DeprecatedAuditLogSerializerAdapter[_]]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "custom audit cluster is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -537,13 +537,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) } "all audit settings are custom" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -563,7 +563,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) @@ -571,7 +571,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } "'data_stream' output type defined" when { "only type is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -588,14 +588,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedDataStreamName = "readonlyrest_audit", expectedAuditCluster = LocalAuditCluster ) } "the output's enabled flag is set" when { "set to true" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -613,13 +613,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedDataStreamName = "readonlyrest_audit", expectedAuditCluster = LocalAuditCluster ) } "set to false" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -637,13 +637,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertSettings( - config, - expectedConfigs = NonEmptyList.of(AuditSink.Disabled) + settings, + expectedAuditSinks = NonEmptyList.of(AuditSink.Disabled) ) } } "custom audit data stream name is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -661,13 +661,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedDataStreamName = "custom_audit_data_stream", expectedAuditCluster = LocalAuditCluster ) } "custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -685,13 +685,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedDataStreamName = "readonlyrest_audit", expectedAuditCluster = LocalAuditCluster ) } "deprecated custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -709,13 +709,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[DeprecatedAuditLogSerializerAdapter[_]]( - config, + settings, expectedDataStreamName = "readonlyrest_audit", expectedAuditCluster = LocalAuditCluster ) } "custom audit cluster is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -733,13 +733,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedDataStreamName = "readonlyrest_audit", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) } "all audit settings are custom" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -759,7 +759,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertDataStreamAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedDataStreamName = "custom_audit_data_stream", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) @@ -776,7 +776,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { EsVersion(7,9,0), ) - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -797,7 +797,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { esVersions.foreach { esVersion => assertDataStreamAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedDataStreamName = "custom_audit_data_stream", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))), esVersion = esVersion @@ -807,7 +807,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } "all output types defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -828,14 +828,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(3) val sink1 = auditingSettings.auditSinks.head @@ -866,7 +866,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } "one of outputs is disabled" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -887,14 +887,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(2) val sink1 = auditingSettings.auditSinks.head @@ -909,10 +909,10 @@ class AuditSettingsTests extends AnyWordSpec with Inside { sink2Config.logSerializer shouldBe a[QueryAuditLogSerializer] } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "'log' output type" when { "not supported custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -930,12 +930,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Class tech.beshu.ror.accesscontrol.blocks.RuleOrdering is not a subclass of tech.beshu.ror.audit.AuditLogSerializer or tech.beshu.ror.requestcontext.AuditLogSerializer" ) } "logger name is empty" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -953,14 +953,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "The audit 'logger_name' cannot be empty" ) } } "'index' output type" when { "not supported custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -978,12 +978,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Class tech.beshu.ror.accesscontrol.blocks.RuleOrdering is not a subclass of tech.beshu.ror.audit.AuditLogSerializer or tech.beshu.ror.requestcontext.AuditLogSerializer" ) } "custom audit index name pattern is invalid" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1001,12 +1001,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Illegal pattern specified for audit_index_template. Have you misplaced quotes? Search for 'DateTimeFormatter patterns' to learn the syntax. Pattern was: invalid pattern error: Unknown pattern letter: i" ) } "remote cluster is empty list" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1024,14 +1024,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Non empty list of valid URI is required" ) } } "'data_stream' output type" when { "not supported custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1049,12 +1049,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Class tech.beshu.ror.accesscontrol.blocks.RuleOrdering is not a subclass of tech.beshu.ror.audit.AuditLogSerializer or tech.beshu.ror.requestcontext.AuditLogSerializer" ) } "data stream name is invalid" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1072,7 +1072,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Illegal format for ROR audit 'data_stream' name - Data stream '.ds-INVALID-data-stream-name#' has an invalid format. Cause: " + "name must be lowercase, " + "name must not contain forbidden characters '\\', '/', '*', '?', '\"', '<', '>', '|', ',', '#', ':', ' ', " + @@ -1081,7 +1081,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { ) } "remote cluster is empty list" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1099,7 +1099,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Non empty list of valid URI is required" ) } @@ -1115,7 +1115,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { EsVersion(5, 0, 5), ) - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1133,7 +1133,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { esVersions.foreach { esVersion => assertInvalidSettings( - config, + settings, expectedErrorMessage = s"Data stream audit output is supported from Elasticsearch version 7.9.0, " + s"but your version is ${esVersion.major}.${esVersion.minor}.${esVersion.revision}. Use 'index' type or upgrade to 7.9.0 or later.", esVersion = esVersion @@ -1142,7 +1142,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } "unknown output type is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1159,12 +1159,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Unsupported 'type' of audit output: custom_type. Supported types: [data_stream, index, log]" ) } "unknown output type is set when using simple format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1180,18 +1180,18 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Unsupported 'type' of audit output: custom_type. Supported types: [data_stream, index, log]" ) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Unsupported 'type' of audit output: custom_type. Supported types: [index, log]", esVersion = EsVersion(7, 8, 0) ) } "'outputs' array is empty" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1207,7 +1207,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "The audit 'outputs' array cannot be empty" ) } @@ -1215,7 +1215,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } "deprecated format is used" should { "ignore deprecated fields when both formats are used at once" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1235,7 +1235,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) @@ -1243,7 +1243,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { "be optional" when { "audit collector is disabled" when { "'audit' section is defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1257,10 +1257,10 @@ class AuditSettingsTests extends AnyWordSpec with Inside { | """.stripMargin) - assertSettingsNoPresent(config) + assertSettingsNoPresent(settings) } "'audit' section is not defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: false @@ -1273,14 +1273,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { | """.stripMargin) - assertSettingsNoPresent(config) + assertSettingsNoPresent(settings) } } } - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "'audit' section is defined" when { "audit collector is enabled" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1295,13 +1295,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "custom audit index name is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1317,13 +1317,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = LocalAuditCluster ) } "custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1339,13 +1339,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "deprecated custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1361,13 +1361,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DeprecatedAuditLogSerializerAdapter[_]]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "custom audit cluster is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1383,13 +1383,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) } "all audit settings are custom" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1407,7 +1407,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) @@ -1415,7 +1415,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } "'audit' section is not defined" when { "audit collector is enabled" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1429,13 +1429,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "custom audit index name is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1450,13 +1450,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = LocalAuditCluster ) } "custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1471,13 +1471,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "deprecated custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1492,13 +1492,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DeprecatedAuditLogSerializerAdapter[_]]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = LocalAuditCluster ) } "custom audit cluster is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1513,13 +1513,13 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[DefaultAuditLogSerializer]( - config, + settings, expectedIndexName = "readonlyrest_audit-2018-12-31", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("user:test@1.1.1.1"))) ) } "all audit settings are custom" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1536,7 +1536,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertIndexBasedAuditSinkSettingsPresent[QueryAuditLogSerializer]( - config, + settings, expectedIndexName = "custom_template_20181231", expectedAuditCluster = RemoteAuditCluster(NonEmptyList.one(Uri.parse("1.1.1.1"))) ) @@ -1544,10 +1544,10 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "'audit' section is defined" when { "not supported custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1563,12 +1563,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Class tech.beshu.ror.accesscontrol.blocks.RuleOrdering is not a subclass of tech.beshu.ror.audit.AuditLogSerializer or tech.beshu.ror.requestcontext.AuditLogSerializer" ) } "custom audit index name pattern is invalid" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1584,12 +1584,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Illegal pattern specified for audit_index_template. Have you misplaced quotes? Search for 'DateTimeFormatter patterns' to learn the syntax. Pattern was: invalid pattern error: Unknown pattern letter: i" ) } "remote cluster is empty list" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit: @@ -1605,14 +1605,14 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Non empty list of valid URI is required" ) } } "'audit' section is not defined" when { "not supported custom serializer is set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1627,12 +1627,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Class tech.beshu.ror.accesscontrol.blocks.RuleOrdering is not a subclass of tech.beshu.ror.audit.AuditLogSerializer or tech.beshu.ror.requestcontext.AuditLogSerializer" ) } "custom audit index name pattern is invalid" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1647,12 +1647,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Illegal pattern specified for audit_index_template. Have you misplaced quotes? Search for 'DateTimeFormatter patterns' to learn the syntax. Pattern was: invalid pattern error: Unknown pattern letter: i" ) } "remote cluster is empty list" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | audit_collector: true @@ -1667,7 +1667,7 @@ class AuditSettingsTests extends AnyWordSpec with Inside { """.stripMargin) assertInvalidSettings( - config, + settings, expectedErrorMessage = "Non empty list of valid URI is required" ) } @@ -1677,48 +1677,48 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertSettingsNoPresent(config: RawRorSettings): Unit = { + private def assertSettingsNoPresent(settings: RawRorSettings): Unit = { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, None))) => } + inside(core) { case Right(Core(_, RorDependencies(_, _, _), None)) => } } - private def assertSettings(config: RawRorSettings, expectedConfigs: NonEmptyList[AuditSink]): Unit = { + private def assertSettings(settings: RawRorSettings, expectedAuditSinks: NonEmptyList[AuditSink]): Unit = { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(settings)))) => - settings.auditSinks should be(expectedConfigs) + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(settings))) => + settings.auditSinks should be(expectedAuditSinks) } } - private def assertIndexBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, + private def assertIndexBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](settings: RawRorSettings, expectedIndexName: NonEmptyString, expectedAuditCluster: AuditCluster) = { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1734,20 +1734,20 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertDataStreamAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, + private def assertDataStreamAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](settings: RawRorSettings, expectedDataStreamName: NonEmptyString, expectedAuditCluster: AuditCluster, esVersion: EsVersion = defaultEsVersionForTests) = { val core = factory(esVersion) .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1763,18 +1763,18 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertLogBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](config: RawRorSettings, + private def assertLogBasedAuditSinkSettingsPresent[EXPECTED_SERIALIZER: ClassTag](settings: RawRorSettings, expectedLoggerName: NonEmptyString) = { val core = factory() .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, NoOpMocksProvider ) .runSyncUnsafe() - inside(core) { case Right(Core(_, RorDependencies(_, _, _, Some(auditingSettings)))) => + inside(core) { case Right(Core(_, RorDependencies(_, _, _), Some(auditingSettings))) => auditingSettings.auditSinks.size should be(1) val headSink = auditingSettings.auditSinks.head @@ -1789,12 +1789,12 @@ class AuditSettingsTests extends AnyWordSpec with Inside { } } - private def assertInvalidSettings(config: RawRorSettings, + private def assertInvalidSettings(settings: RawRorSettings, expectedErrorMessage: String, esVersion: EsVersion = defaultEsVersionForTests): Unit = { val core = factory(esVersion) .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), MockHttpClientsFactory, MockLdapConnectionPoolProvider, diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index f9b5dcea28..e66e36040e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -23,6 +23,7 @@ import org.scalamock.scalatest.MockFactory import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.EnabledAccessControlList import tech.beshu.ror.accesscontrol.blocks.Block import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider @@ -46,7 +47,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { "A RorAclFactory" should { "return headers list" when { "the section is not defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -57,12 +58,12 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) val obfuscatedHeaders = acl.toOption.get.accessControl.staticContext.obfuscatedHeaders obfuscatedHeaders shouldEqual Set(Header.Name.authorization) } "the section exists, and obfuscated header is not defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -74,12 +75,12 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | | obfuscated_headers: [] |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) val headers = acl.toOption.get.accessControl.staticContext.obfuscatedHeaders headers shouldBe empty } "the section exists, and obfuscated header is defined" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -92,7 +93,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | obfuscated_headers: | - CorpoAuth |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) val headers = acl.toOption.get.accessControl.staticContext.obfuscatedHeaders headers should have size 1 headers.head should be(Header.Name(NonEmptyString.unsafeFrom("CorpoAuth"))) @@ -100,7 +101,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } "check policy" when { "allow policy set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -116,8 +117,8 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: test:test | |""".stripMargin) - inside(createCore(config)) { - case Right(Core(acl: EnabledAccessControlList, _)) => + inside(createCore(settings)) { + case Right(Core(acl: EnabledAccessControlList, _, _)) => val firstBlock = acl.blocks.head firstBlock.name should be(Block.Name("test_block1")) firstBlock.policy should be(Block.Policy.Allow) @@ -132,7 +133,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } } "forbid policy set" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -154,8 +155,8 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: test:test | |""".stripMargin) - inside(createCore(config)) { - case Right(Core(acl: EnabledAccessControlList, _)) => + inside(createCore(settings)) { + case Right(Core(acl: EnabledAccessControlList, _, _)) => val firstBlock = acl.blocks.head firstBlock.name should be(Block.Name("test_block1")) firstBlock.policy should be(Block.Policy.Forbid(None)) @@ -178,7 +179,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } "return blocks level error" when { "there is no `access_control_rules` section" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -191,11 +192,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | user_id_header: "X-Auth-Token1" | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message(s"No access_control_rules section found"))))) } "there is `access_control_rules` section defined, but without any block" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -210,11 +211,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | user_id_header: "X-Auth-Token1" | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message(s"access_control_rules defined, but no block found"))))) } "two blocks has the same names" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -235,11 +236,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message(s"Blocks must have unique names. Duplicates: test_block, test_block2"))))) } "block has no name" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -249,7 +250,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(MalformedValue.fromString( """type: "allow" |auth_key: "admin:container" @@ -258,7 +259,7 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } "block has unknown policy type" when { "simple policy format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -269,11 +270,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("Unknown block policy type: unknown. Supported types: 'allow'(default), 'forbid'."))))) } "extended policy format" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -285,13 +286,13 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("Unknown block policy type: unknown. Supported types: 'allow'(default), 'forbid'."))))) } } "block has unknown verbosity" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -302,11 +303,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: admin:container | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("Unknown verbosity value: unknown. Supported types: 'info'(default), 'error'."))))) } "block has authorization rule, but no authentication rule" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -327,11 +328,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | response_group_ids_json_path: "$..groups[?(@.id)].id" | |""".stripMargin) - val acl = createCore(config, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) + val acl = createCore(settings, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("The 'test_block' block contains an authorization rule, but not an authentication rule. This does not mean anything if you don't also set some authentication rule."))))) } "block has many authentication rules" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -350,11 +351,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | user_id_header: "X-Auth-Token" | """.stripMargin) - val acl = createCore(config, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) + val acl = createCore(settings, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("The 'test_block' block should contain only one authentication rule, but contains: [auth_key, proxy_auth]"))))) } "block uses user variable without defining authentication rule beforehand" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -363,11 +364,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | - name: test_block | uri_re: "some_@{user}" |""".stripMargin) - val acl = createCore(config, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) + val acl = createCore(settings, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("The 'test_block' block doesn't meet requirements for defined variables. Variable used to extract user requires one of the rules defined in block to be authentication rule"))))) } "'groups' rule uses jwt variable without defining `jwt_auth` rule beforehand" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -383,13 +384,13 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | auth_key: "user2:pass" | |""".stripMargin) - val acl = createCore(config, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) + val acl = createCore(settings, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient])) acl should be(Left(NonEmptyList.one(BlocksLevelCreationError(Message("The 'test_block' block doesn't meet requirements for defined variables. JWT variables are not allowed to be used in Groups rule"))))) } } "return rule level error" when { "no rules are defined in block" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -399,11 +400,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | type: allow | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(RulesLevelCreationError(Message("No rules defined in block"))))) } "block has unknown rules" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -414,12 +415,12 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | unknown_rule2: value1 | |""".stripMargin) - val acl = createCore(config) + val acl = createCore(settings) acl should be(Left(NonEmptyList.one(RulesLevelCreationError(Message("Unknown rules: unknown_rule1, unknown_rule2"))))) } } - "return ACL with blocks defined in config" in { - val config = rorConfigFromUnsafe( + "return ACL with blocks defined in settings" in { + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -437,8 +438,8 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | |""".stripMargin) - inside(createCore(config)) { - case Right(Core(acl: EnabledAccessControlList, _)) => + inside(createCore(settings)) { + case Right(Core(acl: EnabledAccessControlList, _, _)) => val firstBlock = acl.blocks.head firstBlock.name should be(Block.Name("test_block1")) firstBlock.policy should be(Block.Policy.Forbid(None)) @@ -452,9 +453,9 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { secondBlock.rules should have size 1 } } - "return ACL with blocks defined in config" when { + "return ACL with blocks defined in settings" when { "each block meets requirements for variables" in { - val config = rorConfigFromUnsafe( + val settings = rorSettingsFromUnsafe( """ |readonlyrest: | @@ -468,8 +469,8 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { | uri_re: "/endpoint_@{acl:current_group}" |""".stripMargin) - inside(createCore(config, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient]))) { - case Right(Core(acl: EnabledAccessControlList, _)) => + inside(createCore(settings, new MockHttpClientsFactoryWithFixedHttpClient(mock[HttpClient]))) { + case Right(Core(acl: EnabledAccessControlList, _, _)) => val firstBlock = acl.blocks.head firstBlock.name should be(Block.Name("test_block1")) firstBlock.rules should have size 2 @@ -482,11 +483,11 @@ class CoreFactoryTests extends AnyWordSpec with Inside with MockFactory { } } - private def createCore(config: RawRorSettings, + private def createCore(settings: RawRorSettings, clientsFactory: HttpClientsFactory = MockHttpClientsFactory) = { factory .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, MockLdapConnectionPoolProvider, diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index cd60730c00..67549a4f83 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -21,6 +21,7 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} @@ -36,10 +37,11 @@ import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.* class ImpersonationWarningsTests extends AnyWordSpec with Inside { + "ROR config impersonation warnings" should { "return no warnings" when { "auth key block" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -47,10 +49,10 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | auth_key: admin:container |""".stripMargin - impersonationWarningsReader(config).read() should be(noWarnings) + impersonationWarningsReader(settings).read() should be(noWarnings) } "rules with hashed only password" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -66,14 +68,14 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | auth_key: admin:container |""".stripMargin - impersonationWarningsReader(config).read() should be(noWarnings) + impersonationWarningsReader(settings).read() should be(noWarnings) } "ldap service is mocked" in { val mocksProvider = mocksProviderForLdapFrom( Map(LdapService.Name("ldap1") -> Map.empty) ) - val config = + val settings = s""" |readonlyrest: | @@ -105,14 +107,14 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | search_groups_base_DN: "ou=People,dc=example,dc=com" |""".stripMargin - impersonationWarningsReader(config, mocksProvider).read() should be(noWarnings) + impersonationWarningsReader(settings, mocksProvider).read() should be(noWarnings) } "external authentication service is mocked" in { val mocksProvider = mocksProviderForExternalAuthnServiceFrom( Map(ExternalAuthenticationService.Name("ext1") -> Set.empty) ) - val config = + val settings = s""" |readonlyrest: | @@ -127,14 +129,14 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | authentication_endpoint: "http://localhost:8080/auth1" |""".stripMargin - impersonationWarningsReader(config, mocksProvider).read() should be(noWarnings) + impersonationWarningsReader(settings, mocksProvider).read() should be(noWarnings) } "external authorization service is mocked" in { val mocksProvider = mocksProviderForExternalAuthzServiceFrom( Map(ExternalAuthorizationService.Name("GroupsService1") -> Map.empty) ) - val config = + val settings = """ |readonlyrest: | @@ -157,12 +159,12 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | |""".stripMargin - impersonationWarningsReader(config, mocksProvider).read() should be(noWarnings) + impersonationWarningsReader(settings, mocksProvider).read() should be(noWarnings) } } "return warnings" when { "rules with hashed username and password" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -178,7 +180,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | auth_key: admin:container |""".stripMargin - impersonationWarningsReader(config).read() should be(List( + impersonationWarningsReader(settings).read() should be(List( fullyHashedCredentialsWarning("test_block1", "auth_key_sha1"), fullyHashedCredentialsWarning("test_block2", "auth_key_sha256"), fullyHashedCredentialsWarning("test_block3", "auth_key_sha512"), @@ -186,7 +188,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { )) } "ldap service is not mocked" in { - val config = + val settings = s""" |readonlyrest: | @@ -220,14 +222,14 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { val hint = "Configure a mock of an LDAP service with ID [ldap1]" - impersonationWarningsReader(config).read() should be(List( + impersonationWarningsReader(settings).read() should be(List( notMockedServiceWarning("test_block1", "ldap_auth", "ldap1", hint), notMockedServiceWarning("test_block2", "ldap_authentication", "ldap1", hint), notMockedServiceWarning("test_block3", "ldap_authorization", "ldap1", hint), )) } "external authentication service is not mocked" in { - val config = + val settings = s""" |readonlyrest: | @@ -243,12 +245,12 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { |""".stripMargin val hint = "Configure a mock of an external authentication service with ID [ext1]" - impersonationWarningsReader(config, NoOpMocksProvider).read() should be(List( + impersonationWarningsReader(settings, NoOpMocksProvider).read() should be(List( notMockedServiceWarning("test_block1", "external_authentication", "ext1", hint) )) } "external authorization service is not mocked" in { - val config = + val settings = """ |readonlyrest: | @@ -272,13 +274,13 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { |""".stripMargin val hint = "Configure a mock of an external authorization service with ID [GroupsService1]" - impersonationWarningsReader(config, NoOpMocksProvider).read() should be(List( + impersonationWarningsReader(settings, NoOpMocksProvider).read() should be(List( notMockedServiceWarning("test_block1", "groups_provider_authorization", "GroupsService1", hint) )) } "impersonation not supported by rule" when { "jwt rule" in { - val config = + val settings = """ |readonlyrest: | @@ -294,12 +296,12 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | |""".stripMargin - impersonationWarningsReader(config, NoOpMocksProvider).read() should be(List( + impersonationWarningsReader(settings, NoOpMocksProvider).read() should be(List( impersonationNotSupportedWarning("test_block1", "jwt_auth") )) } "ror kbn auth rule" in { - val config = + val settings = """ |readonlyrest: | @@ -315,7 +317,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | |""".stripMargin - impersonationWarningsReader(config, NoOpMocksProvider).read() should be(List( + impersonationWarningsReader(settings, NoOpMocksProvider).read() should be(List( impersonationNotSupportedWarning("test_block1", "ror_kbn_auth") )) } @@ -361,22 +363,21 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { ) } - private def impersonationWarningsReader(config: String, mocksProvider: MocksProvider = NoOpMocksProvider) = { - val rorConfig = rorConfigFromUnsafe(config) - inside(createCore(config = rorConfig, mocksProvider = mocksProvider)) { - case Right(core) => - core.dependencies.impersonationWarningsReader + private def impersonationWarningsReader(settingsString: String, mocksProvider: MocksProvider = NoOpMocksProvider) = { + val settings = rorSettingsFromUnsafe(settingsString) + inside(createCore(settings, mocksProvider = mocksProvider)) { + case Right(core) => core.dependencies.impersonationWarningsReader } } private implicit val dummyRequestID: RequestId = RequestId("dummy") - private def createCore(config: RawRorSettings, + private def createCore(settings: RawRorSettings, clientsFactory: HttpClientsFactory = MockHttpClientsFactory, mocksProvider: MocksProvider) = { factory .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, new UnboundidLdapConnectionPoolProvider(), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index 52eb436208..c96bb6ee60 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -20,6 +20,7 @@ import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.UnboundidLdapConnectionPoolProvider import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorSettingsIndex, User} @@ -32,10 +33,10 @@ import tech.beshu.ror.utils.TestsUtils.* class LocalUsersTest extends AnyWordSpec with Inside { - "ROR config local users" should { + "ROR setting local users" should { "return info that all users are resolved" when { "auth key block" in { - assertLocalUsersFromConfig( + assertLocalUsersFromSettings( s""" |readonlyrest: | access_control_rules: @@ -46,7 +47,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { ) } "username used in two rules" in { - assertLocalUsersFromConfig( + assertLocalUsersFromSettings( s""" |readonlyrest: | access_control_rules: @@ -59,7 +60,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { ) } "different users defined in rules" in { - assertLocalUsersFromConfig( + assertLocalUsersFromSettings( s""" |readonlyrest: | access_control_rules: @@ -72,7 +73,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { ) } "hashed is only password" in { - assertLocalUsersFromConfig( + assertLocalUsersFromSettings( s""" |readonlyrest: | access_control_rules: @@ -85,7 +86,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { ) } "'proxy_auth' rule" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -131,14 +132,14 @@ class LocalUsersTest extends AnyWordSpec with Inside { | connection_pool_size: 10 # default 30 |""".stripMargin - assertLocalUsersFromConfig( - config, + assertLocalUsersFromSettings( + settings, allUsersResolved(Set(User.Id("admin"), User.Id("dev"))) ) } "users section defined without wildcard patterns" when { "auth_key rules used" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -159,12 +160,12 @@ class LocalUsersTest extends AnyWordSpec with Inside { | auth_key: "user4:pass" |""".stripMargin - assertLocalUsersFromConfig(config, allUsersResolved(Set( + assertLocalUsersFromSettings(settings, allUsersResolved(Set( User.Id("user1"), User.Id("user2"), User.Id("user4"), User.Id("admin") ))) } "ldap_authentication rule used" in { - val config = + val settings = rorSettingsFromUnsafe { s""" |readonlyrest: | access_control_rules: @@ -198,9 +199,9 @@ class LocalUsersTest extends AnyWordSpec with Inside { | groups: | search_groups_base_DN: "ou=People,dc=example,dc=com" |""".stripMargin + } - val rorConfig = rorConfigFromUnsafe(config) - inside(createCore(rorConfig, new UnboundidLdapConnectionPoolProvider())) { + inside(createCore(settings, new UnboundidLdapConnectionPoolProvider())) { case Right(core) => core.dependencies.localUsers should be(allUsersResolved(Set( User.Id("admin"), User.Id("cartman"), User.Id("Bìlbö Bággįnš"), User.Id("bong"), User.Id("morgan") @@ -209,7 +210,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { } } "impersonators section defined with users" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -227,14 +228,14 @@ class LocalUsersTest extends AnyWordSpec with Inside { | auth_key: devAdmin3:pass | users: ["*", "user*"] |""".stripMargin - assertLocalUsersFromConfig(config, expected = allUsersResolved(Set( + assertLocalUsersFromSettings(settings, expected = allUsersResolved(Set( User.Id("admin"), User.Id("user1"), User.Id("user2"), User.Id("user3") ))) } } - "return info that unknown users in config" when { + "return info that unknown users in settings" when { "hashed username and password" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -245,10 +246,10 @@ class LocalUsersTest extends AnyWordSpec with Inside { | - name: test_block3 | auth_key: admin:container |""".stripMargin - assertLocalUsersFromConfig(config, expected = withUnknownUsers(Set(User.Id("admin")))) + assertLocalUsersFromSettings(settings, expected = withUnknownUsers(Set(User.Id("admin")))) } "there is some user with hashed credentials" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -257,10 +258,10 @@ class LocalUsersTest extends AnyWordSpec with Inside { | - name: test_block2 | auth_key: admin:container |""".stripMargin - assertLocalUsersFromConfig(config, withUnknownUsers(Set(User.Id("admin")))) + assertLocalUsersFromSettings(settings, withUnknownUsers(Set(User.Id("admin")))) } "users section defined with wildcard patterns" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -284,7 +285,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { | groups: ["group5", "group6"] | auth_key_sha1: "d27aaf7fa3c1603948bb29b7339f2559dc02019a" |""".stripMargin - assertLocalUsersFromConfig(config, expected = withUnknownUsers(Set( + assertLocalUsersFromSettings(settings, expected = withUnknownUsers(Set( User.Id("admin"), User.Id("user1"), User.Id("user2"), User.Id("user4") ))) } @@ -295,20 +296,20 @@ class LocalUsersTest extends AnyWordSpec with Inside { private def allUsersResolved(users: Set[User.Id]) = LocalUsers(users, unknownUsers = false) - private def assertLocalUsersFromConfig(config: String, expected: LocalUsers) = { - val rorConfig = rorConfigFromUnsafe(config) - inside(createCore(rorConfig)) { + private def assertLocalUsersFromSettings(settingsString: String, expected: LocalUsers) = { + val settings = rorSettingsFromUnsafe(settingsString) + inside(createCore(settings)) { case Right(core) => core.dependencies.localUsers should be(expected) } } - private def createCore(config: RawRorSettings, + private def createCore(settings: RawRorSettings, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider = MockLdapConnectionPoolProvider, clientsFactory: HttpClientsFactory = MockHttpClientsFactory) = { factory .createCoreFrom( - config, + settings, RorSettingsIndex(IndexName.Full(".readonlyrest")), clientsFactory, ldapConnectionPoolProvider, diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala index 2d5153b03c..45a3044815 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/BaseRuleSettingsDecoderTest.scala @@ -49,7 +49,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord protected implicit def envVarsProvider: EnvVarsProvider = OsEnvVarsProvider protected def factory: RawRorSettingsBasedCoreFactory = { - implicit val systemContext: SystemContext = new Environment(envVarsProvider = envVarsProvider) + implicit val systemContext: SystemContext = new SystemContext(envVarsProvider = envVarsProvider) new RawRorSettingsBasedCoreFactory(defaultEsVersionForTests) } @@ -61,14 +61,14 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord inside( aFactory .createCoreFrom( - rorConfigFromUnsafe(yaml), + rorSettingsFromUnsafe(yaml), RorSettingsIndex(IndexName.Full(".readonlyrest")), httpClientsFactory, ldapConnectionPoolProvider, mocksProvider ) .runSyncUnsafe() - ) { case Right(Core(acl: EnabledAccessControlList, _)) => + ) { case Right(Core(acl: EnabledAccessControlList, _, _)) => val rule = acl.blocks.head.rules.collect { case r: T => r }.headOption .getOrElse(throw new IllegalStateException("There was no expected rule in decoding result")) rule shouldBe a[T] @@ -84,7 +84,7 @@ abstract class BaseRuleSettingsDecoderTest[T <: Rule : ClassTag] extends AnyWord inside( aFactory .createCoreFrom( - rorConfigFromUnsafe(yaml), + rorSettingsFromUnsafe(yaml), RorSettingsIndex(IndexName.Full(".readonlyrest")), httpClientsFactory, ldapConnectionPoolProvider, diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index c6ea8fb8fe..36ffc64335 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -16,19 +16,23 @@ */ package tech.beshu.ror.unit.boot +import better.files.File import cats.data.NonEmptyList import cats.effect.Resource import cats.implicits.* import eu.timepit.refined.types.string.NonEmptyString +import io.circe.Json import io.lemonlabs.uri.Uri import monix.eval.Task import monix.execution.Scheduler.Implicits.global +import org.apache.commons.lang.StringEscapeUtils.escapeJava import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.Eventually import org.scalatest.matchers.should.Matchers.* import org.scalatest.time.{Millis, Seconds, Span} import org.scalatest.wordspec.AnyWordSpec import org.scalatest.{EitherValues, Inside, OptionValues} +import squants.information.Bytes import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext @@ -47,11 +51,13 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} -import tech.beshu.ror.es.IndexDocumentReader.{CannotWriteToIndex, DocumentNotFound, IndexNotFound, WriteError} -import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentReader} +import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentManager} +import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider @@ -61,6 +67,7 @@ import java.time.Clock import java.util.UUID import scala.concurrent.duration.* import scala.language.postfixOps +import tech.beshu.ror.es.IndexDocumentManager.{CannotWriteToIndex, DocumentNotFound, IndexNotFound, ReadError, WriteError} class ReadonlyRestStartingTests extends AnyWordSpec @@ -75,28 +82,31 @@ class ReadonlyRestStartingTests "A ReadonlyREST core" should { "support the main engine" should { "be loaded from file" when { - "index is not available but file config is provided" in withReadonlyRest({ - val mockedIndexDocumentReader = mock[IndexDocumentReader] - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "1") - .repeated(1) - .returns(Task.now(Left(IndexNotFound))) - - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - - val coreFactory = mockCoreFactory(mock[CoreFactory], "/boot_tests/no_index_config_file_config_provided/readonlyrest.yml") - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/no_index_config_file_config_provided/") + "index is not available but file settings is provided" in withReadonlyRest({ + val resourcePath = "/boot_tests/no_index_config_file_config_provided" + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) + val coreFactory = mockCoreFactory(mock[CoreFactory], s"$resourcePath/readonlyrest.yml") + + implicit val systemContext: SystemContext = createSystemContext() + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcePath) + ) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] acl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "file loading is forced in elasticsearch.yml" in withReadonlyRest({ - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - - val coreFactory = mockCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading/readonlyrest.yml") - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/forced_file_loading/") + val resourcePath = "/boot_tests/forced_file_loading/" + val coreFactory = mockCoreFactory(mock[CoreFactory], s"$resourcePath/readonlyrest.yml") + implicit val systemContext: SystemContext = createSystemContext() + ( + readonlyRestBoot(coreFactory, mock[IndexDocumentManager]), + forceCreateEsConfigBasedRorSettings(resourcePath) + ) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -104,32 +114,35 @@ class ReadonlyRestStartingTests } } "be loaded from index" when { - "index is available and file config is provided" in withReadonlyRest({ + "index is available and file settings is provided" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - - val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) + val indexSettingsFile = "readonlyrest_index.yml" + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexSettingsFile) + implicit val systemContext: SystemContext = createSystemContext() + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] acl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } - "index is available and file config is not provided" in withReadonlyRest({ + "index is available and file settings is not provided" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - - val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) + val indexSettingsFile = "readonlyrest_index.yml" + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + val coreFactory = mockCoreFactory(mock[CoreFactory], resourcesPath + indexSettingsFile) + implicit val systemContext: SystemContext = createSystemContext() + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -139,26 +152,30 @@ class ReadonlyRestStartingTests "be able to be reloaded" when { "new config is different than old one" in withReadonlyRest({ val resourcesPath = "/boot_tests/config_reloading/" - val initialIndexConfigFile = "readonlyrest_initial.yml" - val newIndexConfigFile = "readonlyrest_first.yml" + val initialIndexSettingsFile = "readonlyrest_initial.yml" + val newIndexSettingsFile = "readonlyrest_first.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + initialIndexConfigFile) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + initialIndexSettingsFile) + mockSavingMainSettings(mockedIndexDocumentManager, resourcesPath + newIndexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + initialIndexConfigFile) - mockCoreFactory(coreFactory, resourcesPath + newIndexConfigFile) - mockIndexJsonContentManagerSaveCall(mockedIndexDocumentReader, resourcesPath + newIndexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) + mockCoreFactory(coreFactory, resourcesPath + initialIndexSettingsFile) + mockCoreFactory(coreFactory, resourcesPath + newIndexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(0 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => val mainEngine = rorInstance.engines.value.mainEngine mainEngine.core.accessControl shouldBe a[AccessControlListLoggingDecorator] mainEngine.core.accessControl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] val reload1Result = rorInstance - .forceReloadAndSave(rorConfigFromResource("/boot_tests/config_reloading/readonlyrest_first.yml"))(newRequestId()) + .forceReloadAndSave(rorSettingsFromResource("/boot_tests/config_reloading/readonlyrest_first.yml"))(newRequestId()) .runSyncUnsafe() reload1Result should be(Right(())) @@ -166,35 +183,40 @@ class ReadonlyRestStartingTests } "two parallel force reloads are invoked" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/config_reloading/" - val initialIndexConfigFile = "readonlyrest_initial.yml" - val firstNewIndexConfigFile = "readonlyrest_first.yml" - val secondNewIndexConfigFile = "readonlyrest_second.yml" + val initialIndexSettingsFile = "readonlyrest_initial.yml" + val firstNewIndexSettingsFile = "readonlyrest_first.yml" + val secondNewIndexSettingsFile = "readonlyrest_second.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + initialIndexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + initialIndexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + initialIndexConfigFile) - mockCoreFactory(coreFactory, resourcesPath + firstNewIndexConfigFile) - mockCoreFactory(coreFactory, resourcesPath + secondNewIndexConfigFile, + mockCoreFactory(coreFactory, resourcesPath + initialIndexSettingsFile) + mockCoreFactory(coreFactory, resourcesPath + firstNewIndexSettingsFile) + mockCoreFactory(coreFactory, resourcesPath + secondNewIndexSettingsFile, createCoreResult = Task .sleep(100 millis) .map(_ => Right(Core(mockEnabledAccessControl, RorDependencies.noOp, None))) // very long creation ) - mockIndexJsonContentManagerSaveCall( - mockedIndexDocumentReader, - resourcesPath + firstNewIndexConfigFile, + mockSavingMainSettings( + mockedIndexDocumentManager, + resourcesPath + firstNewIndexSettingsFile, Task.sleep(500 millis).map(_ => Right(())) // very long saving ) - val readonlyrest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) - (readonlyrest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(0 seconds)) + + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => val resourcesPath = "/boot_tests/config_reloading/" - val firstNewIndexConfigFile = "readonlyrest_first.yml" - val secondNewIndexConfigFile = "readonlyrest_second.yml" + val firstNewIndexSettingsFile = "readonlyrest_first.yml" + val secondNewIndexSettingsFile = "readonlyrest_second.yml" eventually { rorInstance.engines.value.mainEngine.core.accessControl @@ -203,16 +225,16 @@ class ReadonlyRestStartingTests val results = Task .parSequence(List( rorInstance - .forceReloadAndSave(rorConfigFromResource(resourcesPath + firstNewIndexConfigFile))(newRequestId()) + .forceReloadAndSave(rorSettingsFromResource(resourcesPath + firstNewIndexSettingsFile))(newRequestId()) .map { result => // schedule after first finish - mockIndexJsonContentManagerSaveCall(mockedIndexDocumentReader, resourcesPath + secondNewIndexConfigFile) + mockSavingMainSettings(mockedIndexDocumentManager, resourcesPath + secondNewIndexSettingsFile) result }, Task .sleep(200 millis) .flatMap { _ => - rorInstance.forceReloadAndSave(rorConfigFromResource(resourcesPath + secondNewIndexConfigFile))(newRequestId()) + rorInstance.forceReloadAndSave(rorSettingsFromResource(resourcesPath + secondNewIndexSettingsFile))(newRequestId()) } )) .runSyncUnsafe() @@ -221,22 +243,28 @@ class ReadonlyRestStartingTests results should be(Right(List((), ()))) } } - "be reloaded if index config changes" in withReadonlyRest({ + "be reloaded if index settings change" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_reloading/" - val originIndexConfigFile = "readonlyrest.yml" - val updatedIndexConfigFile = "updated_readonlyrest.yml" + val originIndexSettingsFile = "readonlyrest.yml" + val updatedIndexSettingsFile = "updated_readonlyrest.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] + val mockedIndexDocumentManager = mock[IndexDocumentManager] val coreFactory = mock[CoreFactory] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + originIndexConfigFile, repeatedCount = 1) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - mockCoreFactory(coreFactory, resourcesPath + originIndexConfigFile, mockDisabledAccessControl) + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + originIndexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + mockCoreFactory(coreFactory, resourcesPath + originIndexSettingsFile, mockDisabledAccessControl) - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + updatedIndexConfigFile) - mockCoreFactory(coreFactory, resourcesPath + updatedIndexConfigFile) + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + updatedIndexSettingsFile, AttemptCount.AnyNumberOfTimes) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound, AttemptCount.AnyNumberOfTimes) + mockCoreFactory(coreFactory, resourcesPath + updatedIndexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(2 seconds)) + + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => val acl = rorInstance.engines.value.mainEngine.core.accessControl acl shouldBe a[AccessControlListLoggingDecorator] @@ -251,181 +279,203 @@ class ReadonlyRestStartingTests acl2.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "failed to load" when { - "force load from file is set and config is malformed" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/forced_file_loading_malformed_config/") + "force load from file is set and settings is malformed" in { + val resourcesPath = "/boot_tests/forced_file_loading_malformed_config/" + val coreFactory = mock[CoreFactory] + mockCoreFactory(coreFactory, resourcesPath + "readonlyrest.yml", mockEnabledAccessControl) - val result = readonlyRest.start().runSyncUnsafe() + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(coreFactory, mock[IndexDocumentManager]) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) + + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => failure.message should startWith("Settings file is malformed:") } } - "force load from file is set and config cannot be loaded" in { + "force load from file is set and settings cannot be loaded" in { val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading_bad_config/readonlyrest.yml") - val readonlyRest = readonlyRestBoot( - factory = coreFactory, - indexJsonContentService = mockIndexJsonContentManagerSourceOfCallTestConfig(mock[IndexDocumentReader]), - configPath = "/boot_tests/forced_file_loading_bad_config/" - ) - val result = readonlyRest.start().runSyncUnsafe() + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(coreFactory, mock[IndexDocumentManager]) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading_bad_config/") + + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => failure.message shouldBe "Errors:\nfailed" } } - "index config doesn't exist and file config is malformed" in { - val mockedIndexDocumentReader = mock[IndexDocumentReader] - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "1") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + "index settings don't exist and file settings are malformed" in { + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) + + implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentReader, "/boot_tests/index_config_not_exists_malformed_file_config/") + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentManager) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/index_config_not_exists_malformed_file_config/") - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should startWith("Settings content is malformed.") + failure.message should startWith("ROR settings are malformed") } } - "index config doesn't exist and file config cannot be loaded" in { - val mockedIndexDocumentReader = mock[IndexDocumentReader] - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "1") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) + "index settings don't exist and file settings cannot be loaded" in { + val resourcePath = "/boot_tests/index_config_not_exists_bad_file_config/" + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], s"${resourcePath}readonlyrest.yml") + implicit val systemContext: SystemContext = createSystemContext() - val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml") - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, "/boot_tests/index_config_not_exists_bad_file_config/") + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentManager) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcePath) - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => failure.message shouldBe "Errors:\nfailed" } } - "index config is malformed" in { + "index settings are malformed" in { val resourcesPath = "/boot_tests/malformed_index_config/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) + implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentReader, resourcesPath) + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentManager) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => failure.message should startWith("Settings content is malformed.") } } - "index config cannot be loaded" in { + "index settings cannot be loaded" in { val resourcesPath = "/boot_tests/bad_index_config/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) - val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + indexConfigFile) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath) + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + indexSettingsFile) + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentManager) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => failure.message shouldBe "Errors:\nfailed" } } "ROR SSL (in elasticsearch.yml) is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR SSL configuration when XPack Security is enabled") + failure.message should be("Cannot use ROR SSL settings when XPack Security is enabled") } } "ROR SSL (in readonlyrest.yml) is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR SSL configuration when XPack Security is enabled") + failure.message should be("Cannot use ROR SSL settings when XPack Security is enabled") } } "ROR FIPS SSL is tried to be used when XPack Security is enabled" in { - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentReader], "/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR FIBS configuration when XPack Security is enabled") + failure.message should be("Cannot use ROR FIBS settings when XPack Security is enabled") } } } } "support the test engine" which { "can be initialized" when { - "there is no config in index" in withReadonlyRest({ + "there is no settings in index" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(5 seconds)) + + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) } - "there is some config stored in index" should { + "there is some settings stored in index" should { "load test engine as active" when { - "config is still valid" in withReadonlyRestExt({ + "settings are still valid" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> configuredAuthServicesMocksJson, - ) - ))) + val indexSettingsFile = "readonlyrest_index.yml" + val expirationTimestamp = testClock.instant().plusSeconds(100) + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, expirationTimestamp) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + expirationTimestamp + ) }) { case (rorInstance, expirationTimestamp) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) @@ -458,34 +508,37 @@ class ReadonlyRestStartingTests "load test engine as invalidated" when { "the expiration timestamp exceeded" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - + val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().minusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Invalidated( - recent = testConfig1, + recent = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe ) ) @@ -495,20 +548,20 @@ class ReadonlyRestStartingTests "index is not accessible" should { "fallback to not configured" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + val indexSettingsFile = "readonlyrest_index.yml" - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(CannotReachContentSource))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(5 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -518,28 +571,31 @@ class ReadonlyRestStartingTests "settings structure is not valid" should { "fallback to not configured" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - + val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().minusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> "malformed_config", // malformed ror config - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "malformed_settings", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(5 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) @@ -547,35 +603,38 @@ class ReadonlyRestStartingTests } } "settings structure is valid, rule is malformed and cannot start engine" should { - "fallback to invalidated config" in withReadonlyRest({ + "fallback to invalidated settings" in withReadonlyRest({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfigMalformed.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> testClock.instant().plusSeconds(100).toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + val indexSettingsFile = "readonlyrest_index.yml" + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${testSettingsMalformed.raw}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${testClock.instant().plusSeconds(100).toString}", + | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockFailedCoreFactory(coreFactory, testConfigMalformed) + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockFailedCoreFactory(coreFactory, testSettingsMalformed) - readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(5 seconds)) + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(5 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath) + ) }) { rorInstance => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Invalidated( - recent = testConfigMalformed, + recent = testSettingsMalformed, configuredTtl = (100 seconds).toRefinedPositiveUnsafe ) ) @@ -585,326 +644,326 @@ class ReadonlyRestStartingTests "can be loaded on demand" when { "there is no previous engine" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + val indexSettingsFile = "readonlyrest_index.yml" - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig, None) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("60000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("600000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestSettings.Present] - Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { - (testConfig1, 1 minute).some + val testSettingsEngine = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngine shouldBe a[TestSettings.Present] + Option(testSettingsEngine.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { + (testSettings1, 1 minute).some } } "there is previous engine" when { - "same config and ttl" in withReadonlyRestExt({ + "same settings and ttl" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("60000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(2) .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestSettings.Present] - Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { - (testConfig1, 1 minute).some + val testSettingsEngine = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngine shouldBe a[TestSettings.Present] + Option(testSettingsEngine.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { + (testSettings1, 1 minute).some } - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo + val testEngine1Expiration = testSettingsEngine.asInstanceOf[TestSettings.Present].validTo val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestSettings.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { - (testConfig1, 1 minute).some + val testSettingsEngineAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngineAfterReload shouldBe a[TestSettings.Present] + Option(testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { + (testSettings1, 1 minute).some } - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo + val testEngine2Expiration = testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(true) } "different ttl" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("600000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("600000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (10 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (10 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestSettings.Present] - Option(testEngineConfig.asInstanceOf[TestSettings.Present]) - .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig1, 10 minute).some) + val testSettingsEngine = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngine shouldBe a[TestSettings.Present] + Option(testSettingsEngine.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testSettings1, 10 minute).some) - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo + val testEngine1Expiration = testSettingsEngine.asInstanceOf[TestSettings.Present].validTo - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => + (config: IndexName.Full, id: String, document: Json) => config == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("300000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("300000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (5 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (5 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestSettings.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]) - .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig1, 5 minute).some) + val testSettingsEngineAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngineAfterReload shouldBe a[TestSettings.Present] + Option(testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testSettings1, 5 minute).some) - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo + val testEngine2Expiration = testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(false) } } - "different config is being loaded" in withReadonlyRestExt({ + "different settings is being loaded" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + val indexSettingsFile = "readonlyrest_index.yml" - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - mockCoreFactory(coreFactory, testConfig2, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + mockCoreFactory(coreFactory, testSettings2, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("60000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult1stAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult1stAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfig = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfig shouldBe a[TestSettings.Present] - Option(testEngineConfig.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { - (testConfig1, 1 minute).some + val testSettingsEngine = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngine shouldBe a[TestSettings.Present] + Option(testSettingsEngine.asInstanceOf[TestSettings.Present]).map(i => (i.rawSettings, i.configuredTtl.value)) should be { + (testSettings1, 1 minute).some } - val testEngine1Expiration = testEngineConfig.asInstanceOf[TestSettings.Present].validTo + val testEngine1Expiration = testSettingsEngine.asInstanceOf[TestSettings.Present].validTo - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig2.raw) && - content.get("expiration_ttl_millis").contains("120000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings2.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("120000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult2ndAttempt = rorInstance - .forceReloadTestSettingsEngine(testConfig2, (2 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings2, (2 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult2ndAttempt.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] - val testEngineConfigAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() - testEngineConfigAfterReload shouldBe a[TestSettings.Present] - Option(testEngineConfigAfterReload.asInstanceOf[TestSettings.Present]) - .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testConfig2, 2 minutes).some) + val testSettingsEngineAfterReload = rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() + testSettingsEngineAfterReload shouldBe a[TestSettings.Present] + Option(testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present]) + .map(i => (i.rawSettings, i.configuredTtl.value)) should be((testSettings2, 2 minutes).some) - val testEngine2Expiration = testEngineConfigAfterReload.asInstanceOf[TestSettings.Present].validTo + val testEngine2Expiration = testSettingsEngineAfterReload.asInstanceOf[TestSettings.Present].validTo testEngine2Expiration.isAfter(testEngine1Expiration) should be(true) } } - "can be reloaded if index config changes" when { - "new config and expiration time has not exceeded" in withReadonlyRestExt({ + "can be reloaded if index settings changes" when { + "new settings and expiration time has not exceeded" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) - - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile, AttemptCount.Exact(2)) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(2 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) + (mockedIndexDocumentManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + .returns(Task.now(Right(circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + )))) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) @@ -916,61 +975,62 @@ class ReadonlyRestStartingTests rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) ) } - "same config and the ttl has changed" in withReadonlyRestExt({ + "same settings and the ttl has changed" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) - + val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) - + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile, AttemptCount.Exact(2)) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(2 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + (mockedIndexDocumentManager, expirationTimestamp) + ) + }) { case (rorInstance, (mockedIndexDocumentManager, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) ) val expirationTimestamp2 = testClock.instant().plusSeconds(200) - (mockedIndexDocumentReader.documentAsJson _) + (mockedIndexDocumentManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "200000", - "expiration_timestamp" -> expirationTimestamp2.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + .returns(Task.now(Right(circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "200000", + | "expiration_timestamp": "${expirationTimestamp2.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + )))) Task.sleep(5 seconds).runSyncUnsafe() @@ -979,62 +1039,64 @@ class ReadonlyRestStartingTests rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (200 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 ) ) } - "same config and the expiration time has changed" in withReadonlyRestExt({ + "same settings and the expiration time has changed" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) - + val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile, AttemptCount.Exact(2)) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(2 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + (mockedIndexDocumentManager, expirationTimestamp) + ) + }) { case (rorInstance, (mockedIndexDocumentManager, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) ) val expirationTimestamp2 = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) + (mockedIndexDocumentManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp2.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + .returns(Task.now(Right(circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp2.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + )))) Task.sleep(5 seconds).runSyncUnsafe() @@ -1043,62 +1105,64 @@ class ReadonlyRestStartingTests rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp2 ) ) } - "new config and has already expired" in withReadonlyRestExt({ + "new settings and has already expired" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile, 2) - + val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile, AttemptCount.Exact(2)) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings2.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + ) + ) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(2 seconds)) - (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(2 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + (mockedIndexDocumentManager, expirationTimestamp) + ) + }) { case (rorInstance, (mockedIndexDocumentManager, expirationTimestamp)) => rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) ) val expirationTimestamp2 = testClock.instant().minusSeconds(1) - (mockedIndexDocumentReader.documentAsJson _) + (mockedIndexDocumentManager.documentAsJson _) .expects(fullIndexName(".readonlyrest"), "2") .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig2.raw, - "expiration_ttl_millis" -> "200000", - "expiration_timestamp" -> expirationTimestamp2.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, - ) - ))) + .returns(Task.delay(Right(circeJsonFrom( + s"""{ + | "settings": "${escapeJava(testSettings2.raw)}", + | "expiration_ttl_millis": "200000", + | "expiration_timestamp": "${expirationTimestamp2.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |}""".stripMargin + )))) Task.sleep(5 seconds).runSyncUnsafe() @@ -1106,7 +1170,7 @@ class ReadonlyRestStartingTests rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Invalidated( - recent = testConfig2, + recent = testSettings2, configuredTtl = (200 seconds).toRefinedPositiveUnsafe ) ) @@ -1115,43 +1179,44 @@ class ReadonlyRestStartingTests "should be automatically unloaded" when { "engine ttl has reached" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" + val indexSettingsFile = "readonlyrest_index.yml" - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(0 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(0 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager + ) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("3000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (3 seconds).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (3 seconds).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult.value shouldBe a[TestSettings.Present] @@ -1161,65 +1226,64 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( - TestSettings.Invalidated(testConfig1, (3 seconds).toRefinedPositiveUnsafe) + TestSettings.Invalidated(testSettings1, (3 seconds).toRefinedPositiveUnsafe) ) } } "can be invalidated by user" in withReadonlyRestExt({ val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) + val indexSettingsFile = "readonlyrest_index.yml" - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Left(DocumentNotFound))) + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) - - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, mockedIndexDocumentReader) - }) { case (rorInstance, mockedIndexDocumentReader) => + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + mockedIndexDocumentManager) + }) { case (rorInstance, mockedIndexDocumentManager) => rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be(TestSettings.NotSet) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("60000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) .returns(Task.now(Right(()))) val testEngineReloadResult = rorInstance - .forceReloadTestSettingsEngine(testConfig1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(testSettings1, (1 minute).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() testEngineReloadResult.value shouldBe a[TestSettings.Present] rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() shouldBe a[TestSettings.Present] - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => + (config: IndexName.Full, id: String, document: Json) => config == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("60000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .repeated(1) @@ -1229,99 +1293,103 @@ class ReadonlyRestStartingTests rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( - TestSettings.Invalidated(recent = testConfig1, configuredTtl = (1 minute).toRefinedPositiveUnsafe) + TestSettings.Invalidated(recent = testSettings1, configuredTtl = (1 minute).toRefinedPositiveUnsafe) ) } "should return error for invalidation" when { - "cannot save invalidation timestamp in index" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" - val indexConfigFile = "readonlyrest_index.yml" - - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCall(mockedIndexDocumentReader, resourcesPath + indexConfigFile) - - lazy val expirationTimestamp = testClock.instant().plusSeconds(100) - (mockedIndexDocumentReader.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .repeated(1) - .returns(Task.now(Right( - Map( - "settings" -> testConfig1.raw, - "expiration_ttl_millis" -> "100000", - "expiration_timestamp" -> expirationTimestamp.toString, - "auth_services_mocks" -> notConfiguredAuthServicesMocksJson, + "cannot save invalidation timestamp in index" in withReadonlyRestExt( + { + val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val indexSettingsFile = "readonlyrest_index.yml" + lazy val expirationTimestamp = testClock.instant().plusSeconds(100) + + val mockedIndexDocumentManager = mock[IndexDocumentManager] + mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) + mockGettingTestSettings( + mockedIndexDocumentManager, + circeJsonFrom( + s""" + |{ + | "settings": "${escapeJava(testSettings1.raw)}", + | "expiration_ttl_millis": "100000", + | "expiration_timestamp": "${expirationTimestamp.toString}", + | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + |} + |""".stripMargin ) - ))) - - val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + indexConfigFile) - mockCoreFactory(coreFactory, testConfig1, mockEnabledAccessControl, disabledRorConfig) + ) - val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentReader, resourcesPath, refreshInterval = Some(10 seconds)) - (readonlyRest, (mockedIndexDocumentReader, expirationTimestamp)) - }) { case (rorInstance, (mockedIndexDocumentReader, expirationTimestamp)) => + val coreFactory = mock[CoreFactory] + mockCoreFactory(coreFactory, resourcesPath + indexSettingsFile) + mockCoreFactory(coreFactory, testSettings1, mockEnabledAccessControl, RorDependencies.noOp, None) + + implicit val systemContext: SystemContext = createSystemContext(refreshInterval = Some(10 seconds)) + ( + readonlyRestBoot(coreFactory, mockedIndexDocumentManager), + forceCreateEsConfigBasedRorSettings(resourcesPath), + (mockedIndexDocumentManager, expirationTimestamp) + ) + } + ) { case (rorInstance, (mockedIndexDocumentManager, expirationTimestamp)) => rorInstance.engines.value.impersonatorsEngine.value.core.accessControl shouldBe a[AccessControlListLoggingDecorator] rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( TestSettings.Present( dependencies = RorDependencies.noOp, - rawSettings = testConfig1, + rawSettings = testSettings1, configuredTtl = (100 seconds).toRefinedPositiveUnsafe, validTo = expirationTimestamp ) ) - (mockedIndexDocumentReader.saveDocumentJson _) + (mockedIndexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(".readonlyrest") && + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(".readonlyrest") && id == "2" && - content.get("settings").contains(testConfig1.raw) && - content.get("expiration_ttl_millis").contains("100000") && - content.get("expiration_timestamp").exists(_ != expirationTimestamp.toString) + document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("100000") && + document.hcursor.get[String]("expiration_timestamp").toOption.exists(_ != expirationTimestamp.toString) } ) .repeated(1) .returns(Task.now(Left(CannotWriteToIndex))) rorInstance.invalidateTestSettingsEngine()(newRequestId()).runSyncUnsafe() should be( - Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingIndexSettingsError.CannotSaveConfig)) + Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingSettingsError.SourceSpecificError(CannotSaveSettings))) ) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) rorInstance.currentTestSettings()(newRequestId()).runSyncUnsafe() should be( - TestSettings.Invalidated(testConfig1, (100 seconds).toRefinedPositiveUnsafe) + TestSettings.Invalidated(testSettings1, (100 seconds).toRefinedPositiveUnsafe) ) } } } "not be able to be loaded" when { "max size of ROR settings is exceeded" in { - val readonlyRest = readonlyRestBoot( - mock[CoreFactory], - mock[IndexDocumentReader], - "/boot_tests/forced_file_loading/", - maxYamlSize = Some("1 B") - ) + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) + + val esConfigBasedRorSettings = + forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading/") + .copy(settingsMaxSize = Bytes(1)) - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(StartingFailure(message, _)) => - message should include("Settings file is malformed") + message should include("ROR settings are malformed") message should include("The incoming YAML document exceeds the limit: 1 code points") } } "unable to setup data stream audit output" in { - val mockedIndexDocumentReader = mock[IndexDocumentReader] - mockIndexJsonContentManagerSourceOfCallTestConfig(mockedIndexDocumentReader) - val dataStreamSinkConfig1 = AuditSink.Config.EsDataStreamBasedSink.default val dataStreamSinkConfig2 = dataStreamSinkConfig1.copy( auditCluster = AuditCluster.RemoteAuditCluster(NonEmptyList.one(Uri.parse("0.0.0.0"))) ) val coreFactory = mockCoreFactory( - mock[CoreFactory], + mockedCoreFactory = mock[CoreFactory], "/boot_tests/forced_file_loading_with_audit/readonlyrest.yml", mockEnabledAccessControl, RorDependencies(RorDependencies.Services.empty, LocalUsers.empty, NoOpImpersonationWarningsReader), @@ -1329,7 +1397,6 @@ class ReadonlyRestStartingTests NonEmptyList.of( AuditSink.Enabled(dataStreamSinkConfig1), AuditSink.Enabled(dataStreamSinkConfig2)) - ) )) ) @@ -1348,14 +1415,11 @@ class ReadonlyRestStartingTests .once() .returns(mockedDataStreamAuditSinkService(dataStreamService2)) - val readonlyRest = readonlyRestBoot( - coreFactory, - mockedIndexDocumentReader, - "/boot_tests/forced_file_loading_with_audit/", - auditSinkServiceCreator - ) + implicit val systemContext: SystemContext = createSystemContext() + val readonlyRest = readonlyRestBoot(coreFactory, mock[IndexDocumentManager], auditSinkServiceCreator) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading_with_audit/") - val result = readonlyRest.start().runSyncUnsafe() + val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(StartingFailure(message, _)) => val expectedMessage = @@ -1368,17 +1432,19 @@ class ReadonlyRestStartingTests } } - private def withReadonlyRest(readonlyRest: ReadonlyRest)(testCode: RorInstance => Any): Unit = { - withReadonlyRestExt((readonlyRest, ())) { case (rorInstance, ()) => testCode(rorInstance) } + private def withReadonlyRest(readonlyRestAndSettings: (ReadonlyRest, EsConfigBasedRorSettings)) + (testCode: RorInstance => Any): Unit = { + val (readonlyRest, esConfigBasedRorSettings) = readonlyRestAndSettings + withReadonlyRestExt((readonlyRest, esConfigBasedRorSettings, ())) { case (rorInstance, ()) => testCode(rorInstance) } } - private def withReadonlyRestExt[EXT](readonlyRestAndExt: (ReadonlyRest, EXT)) + private def withReadonlyRestExt[EXT](readonlyRestAndSettingsAndExt: (ReadonlyRest, EsConfigBasedRorSettings, EXT)) (testCode: (RorInstance, EXT) => Any): Unit = { - val (readonlyRest, ext) = readonlyRestAndExt + val (readonlyRest, esConfigBasedRorSettings, ext) = readonlyRestAndSettingsAndExt Resource .make( acquire = readonlyRest - .start() + .start(esConfigBasedRorSettings) .flatMap { case Right(startedInstance) => Task.now(startedInstance) case Left(startingFailure) => Task.raiseError(new Exception(s"$startingFailure")) @@ -1394,12 +1460,26 @@ class ReadonlyRestStartingTests .runSyncUnsafe() } - private def readonlyRestBoot(factory: CoreFactory, - indexJsonContentService: IndexDocumentReader, - configPath: String, - auditSinkServiceCreator: AuditSinkServiceCreator = mock[AuditSinkServiceCreator], - refreshInterval: Option[FiniteDuration] = None, - maxYamlSize: Option[String] = None): ReadonlyRest = { + private def forceCreateEsConfigBasedRorSettings(resourceEsConfigDir: String) + (implicit systemContext: SystemContext) = { + createEsConfigBasedRorSettings(resourceEsConfigDir) match { + case Right(settings) => settings + case Left(error) => throw new IllegalStateException(s"Cannot create EsConfigBasedRorSettings: $error") + } + } + + private def createEsConfigBasedRorSettings(resourceEsConfigDir: String) + (implicit systemContext: SystemContext): Either[LoadingError, EsConfigBasedRorSettings] = { + val esConfig = File(getResourcePath(resourceEsConfigDir)) + val esEnv = EsEnv(esConfig, esConfig, defaultEsVersionForTests) + EsConfigBasedRorSettings + .from(esEnv) + .runSyncUnsafe() + .map(settings => settings.copy(settingsFile = RorSettingsFile(esConfig / "readonlyrest.yml"))) + } + + private def createSystemContext(refreshInterval: Option[FiniteDuration] = None, + maxYamlSize: Option[String] = None): SystemContext = { def mapWithIntervalFrom(refreshInterval: Option[FiniteDuration]) = refreshInterval .map(i => "com.readonlyrest.settings.refresh.interval" -> i.toSeconds.toString) @@ -1410,8 +1490,8 @@ class ReadonlyRestStartingTests .map(size => "com.readonlyrest.settings.maxSize" -> size) .toMap - implicit val systemContext: SystemContext = new SystemContext( - propertiesProvider = TestsPropertiesProvider.usingMap( + new SystemContext(propertiesProvider = + TestsPropertiesProvider.usingMap( mapWithIntervalFrom(refreshInterval) ++ mapWithMaxYamlSize(maxYamlSize) ++ Map( @@ -1420,75 +1500,49 @@ class ReadonlyRestStartingTests ) ) ) - - ReadonlyRest.create( - factory, - indexJsonContentService, - auditSinkServiceCreator, - EsEnv(getResourcePath(configPath), getResourcePath(configPath), defaultEsVersionForTests) - ) - } - - private def mockIndexJsonContentManagerSourceOfCall(mockedManager: IndexDocumentReader, - resourceFileName: String, - repeatedCount: Int = 1) = { - (mockedManager.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "1") - .repeated(repeatedCount) - .returns(Task.now(Right( - Map("settings" -> getResourceContent(resourceFileName)) - ))) - mockedManager } - private def mockIndexJsonContentManagerSourceOfCallTestConfig(mockedManager: IndexDocumentReader) = { - (mockedManager.documentAsJson _) - .expects(fullIndexName(".readonlyrest"), "2") - .anyNumberOfTimes() - .returns(Task.now(Left(DocumentNotFound))) - mockedManager - } - - private def mockIndexJsonContentManagerSaveCall(mockedManager: IndexDocumentReader, - resourceFileName: String, - saveResult: Task[Either[WriteError, Unit]] = Task.now(Right(()))) = { - (mockedManager.saveDocumentJson _) - .expects(fullIndexName(".readonlyrest"), "1", Map("settings" -> getResourceContent(resourceFileName))) - .once() - .returns(saveResult) - mockedManager + private def readonlyRestBoot(factory: CoreFactory, + indexDocumentManager: IndexDocumentManager, + auditSinkServiceCreator: AuditSinkServiceCreator = mock[AuditSinkServiceCreator]) + (implicit systemContext: SystemContext): ReadonlyRest = { + ReadonlyRest.create(factory, indexDocumentManager, auditSinkServiceCreator) } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - resourceFileName: String, + loaededMainSettingsResourceFileName: String, accessControlMock: AccessControlList = mockEnabledAccessControl, dependencies: RorDependencies = RorDependencies.noOp, auditingSettings: Option[AuditingTool.Settings] = None): CoreFactory = { - mockCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName), accessControlMock, dependencies, auditingSettings) + mockCoreFactory( + mockedCoreFactory, + rorSettingsFromResource(loaededMainSettingsResourceFileName), + accessControlMock, + dependencies, + auditingSettings + ) } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorSettings, + loadedMainSettings: RawRorSettings, accessControlMock: AccessControlList, dependencies: RorDependencies, auditingSettings: Option[AuditingTool.Settings]): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorSettings, _, _, _, _) => config == rawRorConfig + (settings: RawRorSettings, _, _, _, _) => settings == loadedMainSettings }) .once() .returns(Task.now(Right(Core(accessControlMock, dependencies, auditingSettings)))) mockedCoreFactory } - private def disabledRorConfig = RorDependencies.noOp - private def mockCoreFactory(mockedCoreFactory: CoreFactory, resourceFileName: String, - createCoreResult: Task[Either[NonEmptyList[CoreCreationError], Core]]) = { + createCoreResult: Task[Either[NonEmptyList[CoreCreationError], Core]]): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorSettings, _, _, _, _) => config == rorConfigFromResource(resourceFileName) + (settings: RawRorSettings, _, _, _, _) => settings == rorSettingsFromResource(resourceFileName) }) .once() .returns(createCoreResult) @@ -1497,14 +1551,14 @@ class ReadonlyRestStartingTests private def mockFailedCoreFactory(mockedCoreFactory: CoreFactory, resourceFileName: String): CoreFactory = { - mockFailedCoreFactory(mockedCoreFactory, rorConfigFromResource(resourceFileName)) + mockFailedCoreFactory(mockedCoreFactory, rorSettingsFromResource(resourceFileName)) } private def mockFailedCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorSettings): CoreFactory = { + rawRorSettings: RawRorSettings): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorSettings, _, _, _, _) => config == rawRorConfig + (settings: RawRorSettings, _, _, _, _) => settings == rawRorSettings }) .once() .returns(Task.now(Left(NonEmptyList.one(CoreCreationError.GeneralReadonlyrestSettingsError(Message("failed")))))) @@ -1551,7 +1605,7 @@ class ReadonlyRestStartingTests mockedContext } - private lazy val testConfig1 = rorConfigFromUnsafe( + private lazy val testSettings1 = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: @@ -1563,7 +1617,7 @@ class ReadonlyRestStartingTests |""".stripMargin ) - private lazy val testConfig2 = rorConfigFromUnsafe( + private lazy val testSettings2 = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: @@ -1575,7 +1629,7 @@ class ReadonlyRestStartingTests |""".stripMargin ) - private lazy val testConfigMalformed = rorConfigFromUnsafe( + private lazy val testSettingsMalformed = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: @@ -1641,7 +1695,6 @@ class ReadonlyRestStartingTests private def mockedDataStreamAuditSinkService(dataStreamService: DataStreamService) = { val dataStreamAuditSink = mock[DataStreamBasedAuditSinkService] - (() => dataStreamAuditSink.dataStreamCreator) .expects() .once() @@ -1649,6 +1702,92 @@ class ReadonlyRestStartingTests dataStreamAuditSink } + private def mockGettingMainSettingsReturnsError(mockedManager: IndexDocumentManager, + error: ReadError, + attemptCount: AttemptCount = AttemptCount.Exact(1)) = { + mockGettingSettings( + mockedManager = mockedManager, + expectedIndex = ".readonlyrest", + expectedDocument = "1", + returnsResponse = Task.now(Left(error)), + attemptCount = attemptCount + ) + } + + private def mockGettingMainSettings(mockedManager: IndexDocumentManager, + returnedMainSettingsResourceFileName: String, + attemptCount: AttemptCount = AttemptCount.Exact(1)) = { + mockGettingSettings( + mockedManager = mockedManager, + expectedIndex = ".readonlyrest", + expectedDocument = "1", + returnsResponse = Task.now(Right( + circeJsonFrom(s"""{ "settings": "${escapeJava(getResourceContent(returnedMainSettingsResourceFileName))}"}""") + )), + attemptCount = attemptCount + ) + } + + private def mockGettingTestSettings(mockedManager: IndexDocumentManager, + testSettingsJson: Json, + attemptCount: AttemptCount = AttemptCount.Exact(1)) = { + mockGettingSettings( + mockedManager = mockedManager, + expectedIndex = ".readonlyrest", + expectedDocument = "2", + returnsResponse = Task.now(Right(testSettingsJson)), + attemptCount = attemptCount + ) + } + + private def mockGettingTestSettingsReturnsError(mockedManager: IndexDocumentManager, + error: ReadError, + attemptCount: AttemptCount = AttemptCount.Exact(1)) = { + mockGettingSettings( + mockedManager = mockedManager, + expectedIndex = ".readonlyrest", + expectedDocument = "2", + returnsResponse = Task.now(Left(error)), + attemptCount = attemptCount + ) + } + + private def mockSavingMainSettings(mockedManager: IndexDocumentManager, + resourceFileName: String, + saveResult: Task[Either[WriteError, Unit]] = Task.now(Right(()))) = { + (mockedManager.saveDocumentJson _) + .expects( + fullIndexName(".readonlyrest"), + "1", + circeJsonFrom(s"""{ "settings": "${escapeJava(getResourceContent(resourceFileName))}"}""") + ) + .once() + .returns(saveResult) + mockedManager + } + + private def mockGettingSettings(mockedManager: IndexDocumentManager, + expectedIndex: String, + expectedDocument: String, + returnsResponse: Task[Either[ReadError, Json]], + attemptCount: AttemptCount) = { + val handler = (mockedManager.documentAsJson _) + .expects(fullIndexName(expectedIndex), expectedDocument) + val handlerWithRepetitions = attemptCount match { + case AttemptCount.AnyNumberOfTimes => handler.anyNumberOfTimes() + case AttemptCount.Exact(count) => handler.repeated(count) + } + handlerWithRepetitions + .returns(returnsResponse) + mockedManager + } + + private sealed trait AttemptCount + private object AttemptCount { + case object AnyNumberOfTimes extends AttemptCount + final case class Exact(count: Int) extends AttemptCount + } + // anonymous class instead of mock due to final defs and protected methods in DataStreamService private def mockedDataSteamService(dataStreamExists: Boolean, ilmExists: Boolean = false, diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index 323563032e..fdbd4fc9fb 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -16,9 +16,13 @@ */ package tech.beshu.ror.unit.boot +import better.files.File +import cats.implicits.toShow import eu.timepit.refined.types.string.NonEmptyString +import io.circe.Json import monix.eval.Task import monix.execution.Scheduler.Implicits.global +import org.apache.commons.lang.StringEscapeUtils.escapeJava import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.Eventually import org.scalatest.matchers.should.Matchers.* @@ -28,15 +32,15 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.AccessControlList import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator -import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId} +import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsFile} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.boot.RorInstance.TestSettings import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.es.{EsEnv, IndexDocumentReader} +import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.es.{EsEnv, IndexDocumentManager} +import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* -import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.* import java.util.UUID @@ -51,163 +55,133 @@ class RorIndexTest extends AnyWordSpec private val defaultRorIndexName: NonEmptyString = ".readonlyrest" private val customRorIndexName: NonEmptyString = "custom_ror_index" - private val mainRorConfigDocumentId = "1" - private val testRorConfigDocumentId = "2" + private val mainInIndexRorSettingsDocumentId = "1" + private val testInIndexRorSettingsDocumentId = "2" "A ReadonlyREST core" should { "load ROR index name" when { - "no index is defined in config" should { + "no index is defined in settings" should { "start ROR with default index name" in { - val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) .runSyncUnsafe() result shouldBe a[Right[_, RorInstance]] } - "save ROR config in default index" in { - val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) + "save ROR settings in default index" in { + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) .runSyncUnsafe() result shouldBe a[Right[_, RorInstance]] - mockCoreFactory(coreFactory, rorConfig) - mockMainRorConfigInIndexSaving(indexJsonContentService, defaultRorIndexName) + mockCoreFactory(coreFactory, rorSettings) + mockInIndexMainSettingsSaving(indexDocumentManager, defaultRorIndexName) val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadAndSave(rorConfig)(newRequestId()) + .forceReloadAndSave(rorSettings)(newRequestId()) .runSyncUnsafe() forceReloadingResult should be(Right(())) } - "save ROR test config in default index" in { - val resourcesPath = "/boot_tests/index_config/no_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, defaultRorIndexName) + "save ROR test settings in default index" in { + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) .runSyncUnsafe() result shouldBe a[Right[_, RorInstance]] - mockCoreFactory(coreFactory, rorConfig) - mockTestRorConfigInIndexSaving(indexJsonContentService, defaultRorIndexName) + mockCoreFactory(coreFactory, rorSettings) + mockInIndexTestSettingsSaving(indexDocumentManager, defaultRorIndexName) val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestSettingsEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(rorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() forceReloadingResult.value shouldBe a[TestSettings.Present] } } - "custom index is defined in config" should { + "custom index is defined in settings" should { "start ROR with custom index name" in { - val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) .runSyncUnsafe() result shouldBe a[Right[_, RorInstance]] } - "save ROR config in custom index" in { - val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) + "save ROR settings in custom index" in { + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) .runSyncUnsafe() - mockCoreFactory(coreFactory, rorConfig) - mockMainRorConfigInIndexSaving(indexJsonContentService, customRorIndexName) + mockCoreFactory(coreFactory, rorSettings) + mockInIndexMainSettingsSaving(indexDocumentManager, customRorIndexName) val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadAndSave(rorConfig)(newRequestId()) + .forceReloadAndSave(rorSettings)(newRequestId()) .runSyncUnsafe() forceReloadingResult should be(Right(())) } - "save ROR test config in custom index" in { - val resourcesPath = "/boot_tests/index_config/custom_index_defined/" - val indexJsonContentService = mock[IndexDocumentReader] - mockMainRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) - mockTestRorConfigFromIndexLoading(indexJsonContentService, customRorIndexName) + "save ROR test settings in custom index" in { + val indexDocumentManager = mock[IndexDocumentManager] + mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) + mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, indexRorConfig) - - val result = readonlyRestBoot( - coreFactory, - indexJsonContentService, - resourcesPath - ) - .start() + mockCoreFactory(coreFactory, indexRorSettings) + + val result = readonlyRestBoot(coreFactory, indexDocumentManager) + .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) .runSyncUnsafe() - mockCoreFactory(coreFactory, rorConfig) - mockTestRorConfigInIndexSaving(indexJsonContentService, customRorIndexName) + mockCoreFactory(coreFactory, rorSettings) + mockInIndexTestSettingsSaving(indexDocumentManager, customRorIndexName) val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestSettingsEngine(rorConfig, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(rorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() forceReloadingResult.value shouldBe a[TestSettings.Present] @@ -217,71 +191,58 @@ class RorIndexTest extends AnyWordSpec } private def readonlyRestBoot(factory: CoreFactory, - indexJsonContentService: IndexDocumentReader, - configPath: String) = { - implicit val systemContext: SystemContext = new SystemContext( - propertiesProvider = TestsPropertiesProvider.usingMap( - Map( - "com.readonlyrest.settings.loading.delay" -> "1" - ) - ) - ) - - ReadonlyRest.create( - factory, - indexJsonContentService, - mock[AuditSinkServiceCreator], - EsEnv(getResourcePath(configPath), getResourcePath(configPath), defaultEsVersionForTests) - ) + indexDocumentManager: IndexDocumentManager) = { + implicit val systemContext: SystemContext = SystemContext.default + ReadonlyRest.create(factory, indexDocumentManager, mock[AuditSinkServiceCreator]) } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - rawRorConfig: RawRorSettings): CoreFactory = { + rawRorSettings: RawRorSettings): CoreFactory = { (mockedCoreFactory.createCoreFrom _) .expects(where { - (config: RawRorSettings, _, _, _, _) => config == rawRorConfig + (settings: RawRorSettings, _, _, _, _) => settings == rawRorSettings }) .once() .returns(Task.now(Right(Core(mockAccessControl, RorDependencies.noOp, None)))) mockedCoreFactory } - private def mockMainRorConfigFromIndexLoading(indexJsonContentService: IndexDocumentReader, - indexName: NonEmptyString) = { - (indexJsonContentService.sourceOf _) - .expects(fullIndexName(indexName), mainRorConfigDocumentId) + private def mockInIndexMainSettingsLoading(indexDocumentManager: IndexDocumentManager, + indexName: NonEmptyString) = { + (indexDocumentManager.documentAsJson _) + .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId) .once() - .returns(Task.now(Right(Map("settings" -> indexRorConfig.raw)))) + .returns(Task.now(Right(circeJsonFrom(s"""{ "settings": "${escapeJava(indexRorSettings.raw)}" }""")))) } - private def mockTestRorConfigFromIndexLoading(indexJsonContentService: IndexDocumentReader, - indexName: NonEmptyString) = { - (indexJsonContentService.sourceOf _) - .expects(fullIndexName(indexName), testRorConfigDocumentId) + private def mockInIndexTestSettingsLoading(indexDocumentManager: IndexDocumentManager, + indexName: NonEmptyString) = { + (indexDocumentManager.documentAsJson _) + .expects(fullIndexName(indexName), testInIndexRorSettingsDocumentId) .once() - .returns(Task.now(Left(IndexDocumentReader.DocumentNotFound))) + .returns(Task.now(Left(IndexDocumentManager.DocumentNotFound))) } - private def mockMainRorConfigInIndexSaving(indexJsonContentService: IndexDocumentReader, - indexName: NonEmptyString) = { - (indexJsonContentService.saveContent _) - .expects(fullIndexName(indexName), mainRorConfigDocumentId, Map("settings" -> rorConfig.raw)) + private def mockInIndexMainSettingsSaving(indexDocumentManager: IndexDocumentManager, + indexName: NonEmptyString) = { + (indexDocumentManager.saveDocumentJson _) + .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId, circeJsonFrom(s"""{ "settings": "${escapeJava(rorSettings.raw)}"}""")) .once() .returns(Task.now(Right(()))) } - private def mockTestRorConfigInIndexSaving(indexJsonContentService: IndexDocumentReader, - indexName: NonEmptyString) = { - (indexJsonContentService.saveContent _) + private def mockInIndexTestSettingsSaving(indexDocumentManager: IndexDocumentManager, + indexName: NonEmptyString) = { + (indexDocumentManager.saveDocumentJson _) .expects( where { - (config: IndexName.Full, id: String, content: Map[String, String]) => - config == fullIndexName(indexName) && - id == testRorConfigDocumentId && - content.get("settings").contains(rorConfig.raw) && - content.get("expiration_ttl_millis").contains("300000") && - content.contains("expiration_timestamp") && - content.contains("auth_services_mocks") + (index: IndexName.Full, id: String, document: Json) => + index == fullIndexName(indexName) && + id == testInIndexRorSettingsDocumentId && + document.hcursor.get[String]("settings").toOption.contains(rorSettings.raw) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("300000") && + document.hcursor.downField("expiration_timestamp").succeeded && + document.hcursor.downField("auth_services_mocks").succeeded } ) .once() @@ -317,7 +278,17 @@ class RorIndexTest extends AnyWordSpec private def newRequestId() = RequestId(UUID.randomUUID().toString) - private lazy val rorConfig = rorConfigFromUnsafe( + private def createEsConfigBasedRorSettings(resourceEsConfigDir: String) = { + implicit val systemContext: SystemContext = SystemContext.default + val esConfig = File(getResourcePath(resourceEsConfigDir)) + val esEnv = EsEnv(esConfig, esConfig, defaultEsVersionForTests) + EsConfigBasedRorSettings.from(esEnv).runSyncUnsafe() match { + case Right(settings) => settings.copy(settingsFile = RorSettingsFile(esConfig / "readonlyrest.yml")) + case Left(error) => throw new IllegalStateException(s"Cannot create EsConfigBasedRorSettings: ${error.show}") + } + } + + private lazy val rorSettings = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: @@ -333,7 +304,7 @@ class RorIndexTest extends AnyWordSpec |""".stripMargin ) - private lazy val indexRorConfig = rorConfigFromUnsafe( + private lazy val indexRorSettings = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala deleted file mode 100644 index e613e9ed12..0000000000 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/LoadRawRorSettingsTest.scala +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.unit.configuration - -import cats.{Id, ~>} -import io.circe.Json -import org.scalatest.EitherValues -import org.scalatest.matchers.should.Matchers.* -import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} -import tech.beshu.ror.configuration.RawRorSettings -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} -import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, unsafeNes} - -import java.nio.file.Paths -import scala.concurrent.duration.* -import scala.language.{existentials, postfixOps} - -class LoadRawRorSettingsTest extends AnyWordSpec with EitherValues{ - import LoadRawRorSettingsTest.* - "Free monad loader program" should { - "load forced file" in { - val steps = List( - (ForceLoadRorConfigFromFile(esEnv.configDir), Right(ForcedFileConfig(rawRorConfig))), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromFile(esEnv.configDir) - val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, ForcedFileConfig[RawRorSettings]]] - ffc.value.value shouldEqual rawRorConfig - } - "load successfully from index" in { - val loadingDelay = LoadingDelay.unsafeFrom(2 seconds) - val steps = List( - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Right(IndexConfig(rorConfigurationIndex, rawRorConfig))), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromIndexWithFileFallback( - configurationIndex = rorConfigurationIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(1), - loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configDir - ) - val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] - ffc.value.value shouldEqual rawRorConfig - } - "load successfully from index, after failure" in { - val loadingDelay = LoadingDelay.unsafeFrom(2 seconds) - val loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second) - val steps = List( - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Right(IndexConfig(rorConfigurationIndex, rawRorConfig))), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromIndexWithFileFallback( - configurationIndex = rorConfigurationIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), - loadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfigFilePath = esEnv.configDir - ) - val result = program.foldMap(compiler) - val ffc = result.asInstanceOf[Right[Nothing, IndexConfig[RawRorSettings]]] - ffc.value.value shouldEqual rawRorConfig - } - "load from file when index not exist" in { - val loadingDelay = LoadingDelay.unsafeFrom(2 seconds) - val loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second) - val steps = List( - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingAttemptsInterval.value), Left(LoadedRorConfig.IndexNotExist)), - (LoadRorConfigFromFile(esEnv.configDir), Right(FileConfig(rawRorConfig))), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromIndexWithFileFallback( - configurationIndex = rorConfigurationIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), - loadingAttemptsInterval = loadingAttemptsInterval, - fallbackConfigFilePath = esEnv.configDir - ) - val result = program.foldMap(compiler) - result.toOption.get shouldBe FileConfig(rawRorConfig) - } - "unknown index structure fail loading from index immediately" in { - val loadingDelay = LoadingDelay.unsafeFrom(2 seconds) - val steps = List( - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexUnknownStructure)), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromIndexWithFileFallback( - configurationIndex = rorConfigurationIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), - loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configDir - ) - val result = program.foldMap(compiler) - result shouldBe a[Left[LoadedRorConfig.IndexUnknownStructure.type, _]] - } - "parse index error fail loading from index immediately" in { - val loadingDelay = LoadingDelay.unsafeFrom(2 seconds) - val steps = List( - (LoadRorConfigFromIndex(rorConfigurationIndex, loadingDelay.value), Left(LoadedRorConfig.IndexParsingError("error"))), - ) - val compiler = IdCompiler.instance(steps) - val program = RorMainSettingsManager.loadFromIndexWithFileFallback( - configurationIndex = rorConfigurationIndex, - loadingDelay = loadingDelay, - loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(5), - loadingAttemptsInterval = LoadingAttemptsInterval.unsafeFrom(1 second), - fallbackConfigFilePath = esEnv.configDir - ) - val result = program.foldMap(compiler) - result shouldBe a[Left[LoadedRorConfig.IndexParsingError, _]] - result.left.value.asInstanceOf[LoadedRorConfig.IndexParsingError].message shouldBe "error" - } - } -} -object LoadRawRorSettingsTest { - - private val esEnv = EsEnv(Paths.get("unused_file_path"), Paths.get("unused_file_path"), defaultEsVersionForTests) - private val rawRorConfig = RawRorSettings(Json.False, "forced file config") - private val rorConfigurationIndex = RorSettingsIndex(IndexName.Full("rorConfigurationIndex")) - -} -object IdCompiler { - def instance(mocksDef: List[(LoadRorConfigAction[_], _)]): LoadRorConfigAction ~> Id = new (LoadRorConfigAction ~> Id) { - var mocks: List[(LoadRorConfigAction[_], _)] = mocksDef - - override def apply[A](fa: LoadRorConfigAction[A]): Id[A] = { - val (f1, r) = mocks.head - mocks = mocks.tail - assert(f1 == fa) - r.asInstanceOf[Id[A]] - } - } -} \ No newline at end of file diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala index c15f5e08df..2fd6933118 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala @@ -33,41 +33,41 @@ class RorBootSettingsTest "A ReadonlyREST ES starting settings" should { "be loaded from elasticsearch config file" when { - "configuration contains not started response code" in { - val config = RorBootSettings - .load(esEnvFrom("/boot_tests/boot_config/not_started_code_defined/")) + "boot settings contains not started response code" in { + val settings = RorBootSettings + .load(esEnvFrom("/boot_tests/boot_config/not_started_code_defined")) .runSyncUnsafe() - config.map(_.rorNotStartedResponse) should be(Right( + settings.map(_.rorNotStartedResponse) should be(Right( RorNotStartedResponse(RorNotStartedResponse.HttpCode.`503`) )) } - "configuration contains failed to start response code" in { - val config = RorBootSettings - .load(esEnvFrom("/boot_tests/boot_config/failed_to_start_code_defined/")) + "boot settings contains failed to start response code" in { + val settings = RorBootSettings + .load(esEnvFrom("/boot_tests/boot_config/failed_to_start_code_defined")) .runSyncUnsafe() - config.map(_.rorFailedToStartResponse) should be(Right( + settings.map(_.rorFailedToStartResponse) should be(Right( RorFailedToStartResponse(RorFailedToStartResponse.HttpCode.`503`) )) } - "configuration contains all codes" in { - val config = RorBootSettings - .load(esEnvFrom("/boot_tests/boot_config/all_codes_defined/")) + "boot settings contains all codes" in { + val settings = RorBootSettings + .load(esEnvFrom("/boot_tests/boot_config/all_codes_defined")) .runSyncUnsafe() - config should be(Right(RorBootSettings( + settings should be(Right(RorBootSettings( rorNotStartedResponse = RorNotStartedResponse(RorNotStartedResponse.HttpCode.`403`), rorFailedToStartResponse = RorFailedToStartResponse(RorFailedToStartResponse.HttpCode.`503`), ))) } } "there is no response codes defined in config, default values should be used" in { - val config = RorBootSettings - .load(esEnvFrom("/boot_tests/boot_config/")) + val settings = RorBootSettings + .load(esEnvFrom("/boot_tests/boot_config")) .runSyncUnsafe() - config should be(Right(RorBootSettings( + settings should be(Right(RorBootSettings( rorNotStartedResponse = RorNotStartedResponse(RorNotStartedResponse.HttpCode.`403`), rorFailedToStartResponse = RorFailedToStartResponse(RorFailedToStartResponse.HttpCode.`403`), ))) @@ -75,30 +75,30 @@ class RorBootSettingsTest } "not be able to load" when { "not started response code is malformed" in { - val configFolderPath = "/boot_tests/boot_config/not_started_code_malformed/" - val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString + val esConfigFolderPath = "/boot_tests/boot_config/not_started_code_malformed" + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString - RorBootSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorBootSettings.load(esEnvFrom(esConfigFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( - s"Cannot load ROR boot configuration from file $expectedFilePath. " + + s"Cannot load ROR boot settings from file $expectedFilePath. " + s"Cause: Unsupported response code [200] for readonlyrest.not_started_response_code. Supported response codes are: 403, 503." ) } } "failed to start response code is malformed" in { - val configFolderPath = "/boot_tests/boot_config/failed_to_start_code_malformed/" - val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString + val esConfigFolderPath = "/boot_tests/boot_config/failed_to_start_code_malformed" + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString - RorBootSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + RorBootSettings.load(esEnvFrom(esConfigFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( - s"Cannot load ROR boot configuration from file $expectedFilePath. " + + s"Cannot load ROR boot settings from file $expectedFilePath. " + s"Cause: Unsupported response code [200] for readonlyrest.failed_to_start_response_code. Supported response codes are: 403, 503." ) } } } - private def esEnvFrom(configFolderPath: String) = { - EsEnv(getResourcePath(configFolderPath), getResourcePath(configFolderPath), defaultEsVersionForTests) + private def esEnvFrom(resourceEsConfigFolderPath: String) = { + EsEnv(getResourcePath(resourceEsConfigFolderPath), getResourcePath(resourceEsConfigFolderPath), defaultEsVersionForTests) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala index 9f89fee14e..2a37ed0194 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala @@ -21,12 +21,12 @@ import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext +import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.configuration.SslConfiguration.* import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} -import tech.beshu.ror.configuration.{Environment, MalformedSettings, RorSslSettings} -import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.configuration.{MalformedSettings, RorSslSettings} import tech.beshu.ror.utils.TestsPropertiesProvider -import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} +import tech.beshu.ror.utils.TestsUtils.getResourcePath class SslConfigurationTest extends AnyWordSpec with Inside { @@ -38,42 +38,42 @@ class SslConfigurationTest "A ReadonlyREST ES API SSL settings" should { "be loaded from elasticsearch config file" when { "all properties contain at least one non-digit" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get + val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_elasticsearch_config") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => - keystoreFile.value.getName should be("ror-keystore.jks") + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) - truststoreFile.value.getName should be("ror-truststore.jks") + truststoreFile.value.name should be("ror-truststore.jks") truststorePassword should be(TruststorePassword("readonlyrest3")) allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) } - ssl.interNodeSsl should be(None) + ssl.internodeSsl should be(None) } "some properties contains only digits" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/")).runSyncUnsafe().toOption.get + val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => - keystoreFile.value.getName should be("ror-keystore.jks") + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("123456")) keyPass should be(KeyPass("12")) - truststoreFile.value.getName should be("ror-truststore.jks") + truststoreFile.value.name should be("ror-truststore.jks") truststorePassword should be(TruststorePassword("1234")) allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) } - ssl.interNodeSsl should be(None) + ssl.internodeSsl should be(None) } "server and client are configured using pem files" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get + val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_pem_files") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => - serverCertificateKeyFile.value.getName should be("server_certificate_key.pem") - serverCertificateFile.value.getName should be("server_certificate.pem") - clientTrustedCertificateFile.value.getName should be("client_certificate.pem") + case Some(ExternalSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + serverCertificateKeyFile.value.name should be("server_certificate_key.pem") + serverCertificateFile.value.name should be("server_certificate.pem") + clientTrustedCertificateFile.value.name should be("client_certificate.pem") allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) @@ -82,58 +82,55 @@ class SslConfigurationTest } "be loaded from readonlyrest config file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get + val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_readonlyrest_config") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled)) => - keystoreFile.value.getName should be("ror-keystore.jks") + case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) - truststoreFile.value.getName should be("ror-truststore.jks") + truststoreFile.value.name should be("ror-truststore.jks") truststorePassword should be(TruststorePassword("readonlyrest3")) allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) } - ssl.interNodeSsl should be(None) + ssl.internodeSsl should be(None) } } "be disabled" when { "no ssl section is provided" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/no_es_api_ssl_settings/")).runSyncUnsafe().toOption.get - ssl.externalSsl should be(None) - ssl.interNodeSsl should be(None) + val ssl = loadRorSslSettings("/boot_tests/no_es_api_ssl_settings") + ssl should be (Right(None)) } "it's disabled by proper settings" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_disabled/")).runSyncUnsafe().toOption.get - ssl.externalSsl should be(None) - ssl.interNodeSsl should be(None) + val ssl = loadRorSslSettings("/boot_tests/es_api_ssl_settings_disabled") + ssl should be (Right(None)) } } "not be able to load" when { "SSL settings are malformed" when { "keystore_file entry is missing" in { - val configFolderPath = "/boot_tests/es_api_ssl_settings_malformed/" - val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { - MalformedSettings(s"Cannot load ROR SSL configuration from file $expectedFilePath. Cause: Missing required field") + val esConfigFolderPath = "/boot_tests/es_api_ssl_settings_malformed" + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString + loadRorSslSettings(esConfigFolderPath) shouldBe Left { + MalformedSettings(s"Cannot load ROR SSL settings from file $expectedFilePath. Cause: Missing required field") } } } "file content is not valid yaml" in { - val error = RorSslSettings.load(esEnvFrom("/boot_tests/es_api_ssl_settings_file_invalid_yaml/")).runSyncUnsafe() + val error = loadRorSslSettings("/boot_tests/es_api_ssl_settings_file_invalid_yaml/") inside(error) { case Left(error) => error.message should startWith("Cannot parse file") - } } "SSL settings contain both pem and truststore based configuration" in { - val configFolderPath = "/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/" - val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString + val configFolderPath = "/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured" + val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml").toString - RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { + loadRorSslSettings(configFolderPath) shouldBe Left { MalformedSettings( - s"Cannot load ROR SSL configuration from file $expectedFilePath. " + + s"Cannot load ROR SSL settings from file $expectedFilePath. " + s"Cause: Field sets [server_certificate_key_file, server_certificate_file] and [keystore_file, keystore_pass, key_pass, key_alias] could not be present in the same configuration section") } } @@ -142,10 +139,10 @@ class SslConfigurationTest "A ReadonlyREST internode SSL settings" should { "be loaded from elasticsearch config file" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_elasticsearch_config/")).runSyncUnsafe().toOption.get - inside(ssl.interNodeSsl) { - case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => - keystoreFile.value.getName should be("ror-keystore.jks") + val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_elasticsearch_config") + inside(ssl.internodeSsl) { + case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) truststoreConfiguration should be(None) @@ -153,69 +150,77 @@ class SslConfigurationTest allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) certificateVerificationEnabled should be(true) - hostnameVerificationEnabled should be (true) + hostnameVerificationEnabled should be(true) } ssl.externalSsl should be(None) } "be loaded from elasticsearch config file when pem files are used" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_pem_files/")).runSyncUnsafe().toOption.get - inside(ssl.interNodeSsl) { - case Some(InternodeSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => - serverCertificateKeyFile.value.getName should be("server_certificate_key.pem") - serverCertificateFile.value.getName should be("server_certificate.pem") - clientTrustedCertificateFile.value.getName should be("client_certificate.pem") + val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_pem_files") + inside(ssl.internodeSsl) { + case Some(InternodeSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + serverCertificateKeyFile.value.name should be("server_certificate_key.pem") + serverCertificateFile.value.name should be("server_certificate.pem") + clientTrustedCertificateFile.value.name should be("client_certificate.pem") allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) certificateVerificationEnabled should be(true) - hostnameVerificationEnabled should be (false) + hostnameVerificationEnabled should be(false) } } - "be loaded from readonlyrest config file" when { + "be loaded from readonlyrest settings file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_in_readonlyrest_config/")).runSyncUnsafe().toOption.get - inside(ssl.interNodeSsl) { - case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled)) => - keystoreFile.value.getName should be("ror-keystore.jks") + val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_readonlyrest_config") + inside(ssl.internodeSsl) { + case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) - truststoreFile.value.getName should be("ror-truststore.jks") + truststoreFile.value.name should be("ror-truststore.jks") truststorePassword should be(TruststorePassword("readonlyrest3")) allowedProtocols should be(Set.empty) allowedCiphers should be(Set.empty) clientAuthenticationEnabled should be(false) certificateVerificationEnabled should be(true) - hostnameVerificationEnabled should be (true) + hostnameVerificationEnabled should be(true) } ssl.externalSsl should be(None) } } "be disabled" when { "no ssl section is provided" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/no_internode_ssl_settings/")).runSyncUnsafe().toOption.get - ssl.externalSsl should be(None) - ssl.interNodeSsl should be(None) + val ssl = loadRorSslSettings("/boot_tests/no_internode_ssl_settings") + ssl should be (Right(None)) } "it's disabled by proper settings" in { - val ssl = RorSslSettings.load(esEnvFrom("/boot_tests/internode_ssl_settings_disabled/")).runSyncUnsafe().toOption.get - ssl.externalSsl should be(None) - ssl.interNodeSsl should be(None) + val ssl = loadRorSslSettings("/boot_tests/internode_ssl_settings_disabled") + ssl should be (Right(None)) } } "not be able to load" when { "SSL settings are malformed" when { "keystore_file entry is missing" in { - val configFolderPath = "/boot_tests/internode_ssl_settings_malformed/" - val expectedFilePath = getResourcePath(s"${configFolderPath}elasticsearch.yml").toString - RorSslSettings.load(esEnvFrom(configFolderPath)).runSyncUnsafe() shouldBe Left { - MalformedSettings(s"Cannot load ROR SSL configuration from file $expectedFilePath. Cause: Missing required field") + val configFolderPath = "/boot_tests/internode_ssl_settings_malformed" + val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml").toString + loadRorSslSettings(configFolderPath) shouldBe Left { + MalformedSettings(s"Cannot load ROR SSL settings from file $expectedFilePath. Cause: Missing required field") } } } } } - private def esEnvFrom(configFolderPath: String) = { - EsEnv(getResourcePath(configFolderPath), getResourcePath(configFolderPath), defaultEsVersionForTests) + private def forceLoadRorSslSettings(settingsFolderPath: String) = { + loadRorSslSettings(settingsFolderPath) + .toOption.flatten.get + } + + private def loadRorSslSettings(settingsFolderPath: String) = { + RorSslSettings + .load( + RorSettingsFile(getResourcePath(s"$settingsFolderPath/readonlyrest.yml")), + getResourcePath(s"$settingsFolderPath/elasticsearch.yml") + ) + .runSyncUnsafe() } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala index d75105a3f4..3dd74a13b9 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala @@ -22,11 +22,12 @@ import io.circe.Decoder import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec -import tech.beshu.ror.configuration.{Environment, YamlFileBasedSettingsLoader} +import tech.beshu.ror.SystemContext +import tech.beshu.ror.configuration.YamlFileBasedSettingsLoader class YamlFileBasedRorSettingsLoaderTest extends AnyWordSpec with Inside { - private implicit val systemContext: SystemContext = new Environment( + private implicit val systemContext: SystemContext = new SystemContext( envVarsProvider = name => name.value.value match { case "USER_NAME" => Some("John") diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala index eb96fd4333..ab0d25b42f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala @@ -16,7 +16,7 @@ */ package tech.beshu.ror.unit.utils -import io.circe.{Json, ParsingFailure} +import io.circe.Json import org.scalatest.Inside import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -29,7 +29,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { "Yaml parser" should { "return parsing failure error" when { "readonlyrest config has duplicated 'readonlyrest' section" in { - val result = rorConfigFrom( + val result = rorSettingFrom( """ |readonlyrest: | @@ -57,7 +57,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } } "readonlyrest config has duplicated 'access_control_rules' section" in { - val result = rorConfigFrom( + val result = rorSettingFrom( """ |readonlyrest: | @@ -83,7 +83,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } } "readonlyrest config has duplicated definition" in { - val result = rorConfigFrom( + val result = rorSettingFrom( """ |readonlyrest: | @@ -112,7 +112,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } } "block has duplicated rule" in { - val result = rorConfigFrom( + val result = rorSettingFrom( """ |readonlyrest: | @@ -160,7 +160,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { | |""".stripMargin - val result = rorConfigFrom(rawConfig) + val result = rorSettingFrom(rawConfig) inside(result) { case Right(config) => config.raw shouldBe rawConfig @@ -196,7 +196,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { | auth_key: "admin:container" |""".stripMargin - val result = new YamlParser(Bytes(10)).parse(yamlContent) + val result = new YamlParser(Some(Bytes(10))).parse(yamlContent) inside(result) { case Left(parsingFailure) => parsingFailure.message should be("The incoming YAML document exceeds the limit: 10 code points.") @@ -205,5 +205,5 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } private def parseYaml(yamlContent: String): Json = - new YamlParser(Kilobytes(100)).parse(yamlContent).toTry.get + new YamlParser(Some(Kilobytes(100))).parse(yamlContent).toTry.get } diff --git a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala index bb0813ef39..33dfb4bd2d 100644 --- a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala +++ b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.utils import better.files.File import cats.data.{EitherT, NonEmptyList} import eu.timepit.refined.types.string.NonEmptyString -import io.circe.ParsingFailure +import io.circe.{Json, ParsingFailure, parser} import io.jsonwebtoken.JwtBuilder import io.lemonlabs.uri.Url import monix.eval.Task @@ -69,7 +69,7 @@ import scala.util.{Failure, Success} object TestsUtils { implicit val loggingContext: LoggingContext = LoggingContext(Set.empty) - val rorYamlParser = new YamlParser(Megabytes(3)) + val rorYamlParser = new YamlParser(Some(Megabytes(3))) val defaultEsVersionForTests: EsVersion = EsVersion(8, 17, 0) @@ -379,18 +379,18 @@ object TestsUtils { def nel: NonEmptyList[T] = NonEmptyList.one(value) } - def rorConfigFromUnsafe(yamlContent: String): RawRorSettings = { - rorConfigFrom(yamlContent).toOption.get + def rorSettingsFromUnsafe(yamlContent: String): RawRorSettings = { + rorSettingFrom(yamlContent).toOption.get } - def rorConfigFrom(yamlContent: String): Either[ParsingFailure, RawRorSettings] = { + def rorSettingFrom(yamlContent: String): Either[ParsingFailure, RawRorSettings] = { rorYamlParser .parse(yamlContent) .map(json => RawRorSettings(json, yamlContent)) } - def rorConfigFromResource(resource: String): RawRorSettings = { - rorConfigFromUnsafe { + def rorSettingsFromResource(resource: String): RawRorSettings = { + rorSettingsFromUnsafe { getResourceContent(resource) } } @@ -403,6 +403,10 @@ object TestsUtils { File(getResourcePath(resource)).contentAsString } + def circeJsonFrom(jsonString: String): Json = { + parser.parse(jsonString).toTry.get + } + implicit class ValueOrIllegalState[ERROR, SUCCESS](private val eitherT: EitherT[Task, ERROR, SUCCESS]) extends AnyVal { def valueOrThrowIllegalState()(implicit scheduler: Scheduler): SUCCESS = { diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index ba2ed0880f..3e64256cb3 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -39,7 +39,7 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexDocumentReader, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.exceptions.StartingFailureException @@ -69,7 +69,7 @@ class IndexLevelActionFilter(nodeName: String, new RorNotAvailableRequestHandler(esConfig.boot) private val ror = ReadonlyRest.create( - new EsIndexDocumentReader(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, EsEnvProvider.create(env) ) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 94% rename from es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala rename to es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 39b39361c9..486545fa93 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentReader.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -29,15 +29,15 @@ import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexDocumentReader -import tech.beshu.ror.es.IndexDocumentReader.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* import scala.annotation.unused -class EsIndexDocumentReader(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexDocumentReader +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject From 375262655686a174c362e1d6a44d481b50d46e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 12 Sep 2025 11:07:46 +0200 Subject: [PATCH 034/103] wip --- .../tech/beshu/ror/api/MainSettingsApi.scala | 4 +- .../tech/beshu/ror/boot/RorInstance.scala | 69 +++++++-- .../beshu/ror/boot/engines/SettingsHash.scala | 2 +- .../ror/configuration/RawRorSettings.scala | 2 +- .../ror/configuration/RorSslSettings.scala | 6 +- .../ForceLoadRorSettingsFromFileLoader.scala | 2 +- ...hFileSourceFallbackRorSettingsLoader.scala | 8 +- .../settings/source/RawRorSettingsCodec.scala | 2 +- .../ror/settings/source/SettingsSource.scala | 2 +- .../bad_index_config/readonlyrest_index.yml | 9 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 7 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../forced_file_loading/readonlyrest.yml | 2 +- .../readonlyrest.yml | 7 +- .../readonlyrest.yml | 8 +- .../readonlyrest.yml | 8 +- .../custom_index_defined/readonlyrest.yml | 8 +- .../no_index_defined/readonlyrest.yml | 8 +- .../readonlyrest_index.yml | 9 +- .../readonlyrest.yml | 2 +- .../readonlyrest.yml | 9 +- .../readonlyrest.yml | 9 +- .../index_config_reloading/readonlyrest.yml | 9 +- .../updated_readonlyrest.yml | 9 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 8 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 6 +- .../malformed_index_config/readonlyrest.yml | 8 +- .../readonlyrest_index.yml | 9 +- .../no_es_api_ssl_settings/readonlyrest.yml | 6 +- .../readonlyrest.yml | 2 +- .../readonlyrest.yml | 6 +- .../readonlyrest.yml | 14 +- .../readonlyrest.yml | 8 +- .../readonlyrest.yml | 8 +- .../unit/boot/ReadonlyRestStartingTests.scala | 145 ++++++++---------- .../beshu/ror/unit/boot/RorIndexTest.scala | 6 +- .../ror/unit/utils/RorYamlParserTests.scala | 2 +- .../rrtestconfig/RRTestConfigResponse.scala | 4 +- 47 files changed, 214 insertions(+), 279 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala index 5126a81db9..2dec3561ce 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala @@ -89,7 +89,7 @@ class MainSettingsApi(rorInstance: RorInstance, mainSettingsFileSource .load() .map { - case Right(settings) => ProvideFileMainSettings.MainSettings(settings.rawSettings.raw) + case Right(settings) => ProvideFileMainSettings.MainSettings(settings.rawSettings.rawYaml) case Left(error) => ProvideFileMainSettings.Failure(error.show) } } @@ -99,7 +99,7 @@ class MainSettingsApi(rorInstance: RorInstance, .load() .map { case Right(settings) => - ProvideIndexMainSettings.MainSettings(settings.rawSettings.raw) + ProvideIndexMainSettings.MainSettings(settings.rawSettings.rawYaml) case Left(SourceSpecificError(error@IndexNotFound)) => ProvideIndexMainSettings.MainSettingsNotFound(Show[IndexSettingsSource.LoadingError].show(error)) case Left(error) => diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index b0f8ea62f8..4abf3174a5 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -23,6 +23,8 @@ import cats.syntax.either.* import monix.catnap.Semaphore import monix.eval.Task import monix.execution.{Cancelable, Scheduler} + +import java.util.concurrent.atomic.AtomicReference import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} @@ -58,12 +60,13 @@ class RorInstance private(boot: ReadonlyRest, import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} logger.info("ReadonlyREST was loaded ...") - private val enginesReloadTask = mode match { + private val reloadTaskState: AtomicReference[ReloadTaskState] = new AtomicReference(ReloadTaskState.NotInitiated) + + mode match { case Mode.WithPeriodicIndexCheck(RefreshInterval.Enabled(interval)) => scheduleEnginesReload(interval) case Mode.WithPeriodicIndexCheck(RefreshInterval.Disabled) | Mode.NoPeriodicIndexCheck => logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") - Cancelable.empty } private val theMainSettingsEngine = mainSettingsBasedReloadableEngineCreator.create( @@ -125,13 +128,20 @@ class RorInstance private(boot: ReadonlyRest, def stop(): Task[Unit] = { implicit val requestId: RequestId = RequestId("ES sigterm") for { - _ <- Task.delay(enginesReloadTask.cancel()) + _ <- Task.delay(logger.info("ReadonlyREST is stopping ...")) + currentState <- Task.delay(reloadTaskState.getAndSet(ReloadTaskState.Stopped)) + _ <- Task.delay(currentState match { + case ReloadTaskState.NotInitiated => // do nothing + case ReloadTaskState.Running(cancelable) => cancelable.cancel() + case ReloadTaskState.Stopped => // do nothing + }) _ <- theTestSettingsEngine.stop() _ <- theMainSettingsEngine.stop() + _ <- Task.delay(logger.info("ReadonlyREST is stopped!")) } yield () } - private def scheduleEnginesReload(interval: PositiveFiniteDuration): Cancelable = { + private def scheduleEnginesReload(interval: PositiveFiniteDuration): Unit = { val reloadTask = { (requestId: RequestId) => Task.sequence { Seq( @@ -140,26 +150,47 @@ class RorInstance private(boot: ReadonlyRest, ) } } - scheduleIndexSettingsChecking(interval, reloadTask) + scheduleNextIfNotStopping(interval, reloadTask) + } + + private def scheduleNextIfNotStopping(interval: PositiveFiniteDuration, + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Unit = { + implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) + val nextTask = scheduleIndexSettingsChecking(interval, reloadTask) + trySetNextReloadTask(nextTask) match { + case ReloadTaskState.NotInitiated => // nothing to do + case ReloadTaskState.Running(_) => // nothing to do + case ReloadTaskState.Stopped => nextTask.cancel() + } } // todo: check messages private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, - reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Cancelable = { - logger.debug(s"[CLUSTERWIDE SETTINGS] Scheduling next in-index settings check within ${interval.show}") - scheduler.scheduleOnce(interval.value) { - implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) + (implicit requestId: RequestId): CancelableWithRequestId = { + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check within ${interval.show}") + val cancellable = scheduler.scheduleOnce(interval.value) { logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") reloadTask(requestId) .runAsync { case Right(reloadResults) => reloadResults.foreach(logSettingsReloadResult) - scheduleIndexSettingsChecking(interval, reloadTask) + scheduleNextIfNotStopping(interval, reloadTask) case Left(ex) => logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) - scheduleIndexSettingsChecking(interval, reloadTask) + scheduleNextIfNotStopping(interval, reloadTask) } } + new CancelableWithRequestId(cancellable, requestId) + } + + private def trySetNextReloadTask(nextTask: CancelableWithRequestId) = { + reloadTaskState.updateAndGet { + case ReloadTaskState.NotInitiated | ReloadTaskState.Running(_) => + ReloadTaskState.Running(nextTask) + case ReloadTaskState.Stopped => + ReloadTaskState.Stopped + } } private def logSettingsReloadResult(settingsReloadResult: (SettingsType, Either[ScheduledReloadError, Unit])) @@ -311,5 +342,21 @@ object RorInstance { case Test => "test" } } + + private sealed trait ReloadTaskState + private object ReloadTaskState { + case object NotInitiated extends ReloadTaskState + final case class Running(cancelable: CancelableWithRequestId) extends ReloadTaskState + case object Stopped extends ReloadTaskState + } + + private final class CancelableWithRequestId(cancelable: Cancelable, requestId: RequestId) + extends Logging { + + def cancel(): Unit = { + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check cancelled!") + cancelable.cancel() + } + } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala index 84c380e8b6..856634f024 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala @@ -23,7 +23,7 @@ import scala.language.implicitConversions private[engines] class SettingsHash(val settings: RawRorSettings) extends AnyVal { - def hashString(): String = Hasher.Sha1.hashString(settings.raw) + def hashString(): String = Hasher.Sha1.hashString(settings.rawYaml) } private[engines] object SettingsHash { diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala index 53a2b091ab..24d15b048e 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.configuration import cats.Eq import io.circe.Json -final case class RawRorSettings(settingsJson: Json, raw: String) +final case class RawRorSettings(settingsJson: Json, rawYaml: String) object RawRorSettings { implicit val eq: Eq[RawRorSettings] = Eq.fromUniversalEquals } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala index a992c89c86..df97004b0c 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala @@ -288,11 +288,13 @@ private object SslDecoders extends Logging { for { fipsMode <- c.downField(consts.rorSection).downField(consts.fipsMode).as[Option[FipsMode]] interNodeSsl <- { - implicit val internodeSslConfigDecoder = sslInternodeConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + implicit val internodeSslConfigDecoder: Decoder[Option[InternodeSslSettings]] = + sslInternodeConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslSettings]]] } externalSsl <- { - implicit val externalSslConfigDecoder = sslExternalConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + implicit val externalSslConfigDecoder: Decoder[Option[ExternalSslSettings]] = + sslExternalConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslSettings]]] } } yield { diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala index a4e6bdf39f..d119310bbb 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala @@ -34,7 +34,7 @@ class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSou settings <- EitherT(mainSettingsFileSource.load()) .biSemiflatTap( error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file: ${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file: ${settings.rawSettings.rawYaml.show}") ) .leftMap(error => StartingFailure(error.show)) } yield (settings, None) diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala index 216300ba07..d89cb5d60c 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -48,7 +48,7 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn loadedSettings <- EitherT(mainSettingsIndexSource.load()) .biSemiflatTap( error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index:\n${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index:\n${settings.rawSettings.rawYaml.show}") ) .leftMap(error => StartingFailure(error.show)) } yield loadedSettings @@ -60,7 +60,7 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn loadedSettings <- EitherT(mainSettingsFileSource.load()) .biSemiflatTap( error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file:\n${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file:\n${settings.rawSettings.rawYaml.show}") ) .leftMap(error => StartingFailure(error.show)) } yield loadedSettings @@ -68,11 +68,11 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn private def loadTestSettingsFromIndex() = { for { - _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${testSettingsIndexSource.settingsIndex.show}) ...")) + _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index: ${testSettingsIndexSource.settingsIndex.show} ...")) loadedSettings <- EitherT(testSettingsIndexSource.load()) .biSemiflatTap( error => logger.dInfo(s"Loading ReadonlyREST test settings from index failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${settings.rawSettings.raw.show}") + settings => logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${settings.rawSettings.rawYaml.show}") ) .leftMap(error => StartingFailure(error.show)) .map(Option(_)) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala index e57dc16213..f83574af2f 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala @@ -35,5 +35,5 @@ private [source] class RawRorSettingsCodec(yamlParser: RawRorSettingsYamlParser) .apply(c) override def apply(a: RawRorSettings): Json = - Json.fromString(a.raw) + Json.fromString(a.rawYaml) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala index 083f485834..ac4b55a28c 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala @@ -35,7 +35,7 @@ object ReadOnlySettingsSource { } implicit def show[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { - case LoadingSettingsError.SettingsMalformed(cause) => "ROR settings are malformed" + case LoadingSettingsError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) } } diff --git a/core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml b/core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml index 1ed9fb2b66..3cc437d0a8 100644 --- a/core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml +++ b/core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + unknown_rule: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_disabled/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_file_invalid_yaml/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml index 3e92390c77..dcdb50d7c7 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml @@ -9,8 +9,5 @@ readonlyrest: truststore_pass: readonlyrest3 access_control_rules: - - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_malformed/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/es_api_ssl_settings_pem_files/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml index 49b9cc0c4d..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading/readonlyrest.yml @@ -1,4 +1,4 @@ readonlyrest: access_control_rules: - - name: "Admin block" + - name: "ADMIN" auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml index 1ed9fb2b66..a68f8684ea 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow + - name: "ADMIN" unknown_rule: admin:container \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml index 3815fac3ba..1577c48520 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml @@ -1,8 +1,4 @@ readonlyrest: - access_control_rules: - - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key_1: "admin:container" \ No newline at end of file + - name: "ADMIN" + auth_key: "admin:admin # wrong YAML \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/forced_file_loading_with_audit/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_with_audit/readonlyrest.yml index 58d8e43093..c5c6786aed 100644 --- a/core/src/test/resources/boot_tests/forced_file_loading_with_audit/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/forced_file_loading_with_audit/readonlyrest.yml @@ -5,9 +5,5 @@ readonlyrest: outputs: [ index, data_stream ] access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - aut h_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml index 0b14130e53..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml @@ -1,8 +1,4 @@ readonlyrest: - access_control_rules: - - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml index 0b14130e53..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml @@ -1,8 +1,4 @@ readonlyrest: - access_control_rules: - - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml b/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml index 728b72e827..2907698ccc 100644 --- a/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml +++ b/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "INDEX MODIFIED: CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "INDEX MODIFIED: ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml index 49b9cc0c4d..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml @@ -1,4 +1,4 @@ readonlyrest: access_control_rules: - - name: "Admin block" + - name: "ADMIN" auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml index 1ed9fb2b66..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml index 78af795426..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: "admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml index 52df94de84..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml b/core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml index e745b695ab..ebf46b3711 100644 --- a/core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml +++ b/core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN - changed" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN - changed" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_disabled/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_in_elasticsearch_config/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml index f9473929b0..d8003efdb6 100644 --- a/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml @@ -11,9 +11,5 @@ readonlyrest: hostname_verification: true access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_malformed/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/internode_ssl_settings_pem_files/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml index 85a27f8fd6..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml @@ -1,8 +1,4 @@ readonlyrest: - access_control_rules: - - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: "admin:container" \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml index 78af795426..ad55e12c81 100644 --- a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml +++ b/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml @@ -1,9 +1,4 @@ readonlyrest: - access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: "admin:container \ No newline at end of file + - name: "MODIFIED: ADMIN" + auth_key: "admin:admin # wrong YAML \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml b/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/no_es_api_ssl_settings/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml index 49b9cc0c4d..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml @@ -1,4 +1,4 @@ readonlyrest: access_control_rules: - - name: "Admin block" + - name: "ADMIN" auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml b/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml index 61be106845..de26466d1e 100644 --- a/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/no_internode_ssl_settings/readonlyrest.yml @@ -1,6 +1,4 @@ readonlyrest: access_control_rules: - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - unknown_rule: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml b/core/src/test/resources/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml index b61794270e..39b656d917 100644 --- a/core/src/test/resources/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml @@ -1,10 +1,12 @@ readonlyrest: + fips_mode: SSL_ONLY + ssl: + enable: true + keystore_file: "ror-keystore.jks" + keystore_pass: readonlyrest + key_pass: readonlyrest access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml index 83d570b987..3aeb9c309d 100644 --- a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml @@ -10,9 +10,5 @@ readonlyrest: certificate_verification: true access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml b/core/src/test/resources/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml index 83d570b987..3aeb9c309d 100644 --- a/core/src/test/resources/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/readonlyrest.yml @@ -10,9 +10,5 @@ readonlyrest: certificate_verification: true access_control_rules: - - # ES container initializer need this rule to configure ES instance after startup - - name: "CONTAINER ADMIN" - verbosity: error - type: allow - auth_key: admin:container \ No newline at end of file + - name: "ADMIN" + auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 36ffc64335..a6ced5f907 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -55,6 +55,7 @@ import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentManager} import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError @@ -67,7 +68,6 @@ import java.time.Clock import java.util.UUID import scala.concurrent.duration.* import scala.language.postfixOps -import tech.beshu.ror.es.IndexDocumentManager.{CannotWriteToIndex, DocumentNotFound, IndexNotFound, ReadError, WriteError} class ReadonlyRestStartingTests extends AnyWordSpec @@ -279,27 +279,22 @@ class ReadonlyRestStartingTests acl2.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "failed to load" when { - "force load from file is set and settings is malformed" in { + "force load from file is set and settings file is malformed yaml" in { val resourcesPath = "/boot_tests/forced_file_loading_malformed_config/" - val coreFactory = mock[CoreFactory] - mockCoreFactory(coreFactory, resourcesPath + "readonlyrest.yml", mockEnabledAccessControl) - implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(coreFactory, mock[IndexDocumentManager]) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) + val result = createEsConfigBasedRorSettings(resourcesPath) - val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() - - inside(result) { case Left(failure) => - failure.message should startWith("Settings file is malformed:") + inside(result) { case Left(LoadingError.MalformedContent(_, message)) => + message should startWith("Cannot parse file") } } - "force load from file is set and settings cannot be loaded" in { - val coreFactory = mockFailedCoreFactory(mock[CoreFactory], "/boot_tests/forced_file_loading_bad_config/readonlyrest.yml") + "force load from file is set and core cannot be loaded" in { + val resourcesPath = "/boot_tests/forced_file_loading_bad_config/" + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + "readonlyrest.yml") implicit val systemContext: SystemContext = createSystemContext() val readonlyRest = readonlyRestBoot(coreFactory, mock[IndexDocumentManager]) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading_bad_config/") + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() @@ -307,28 +302,31 @@ class ReadonlyRestStartingTests failure.message shouldBe "Errors:\nfailed" } } - "index settings don't exist and file settings are malformed" in { + "index settings don't exist and settings file is malformed yaml" in { + val resourcesPath = "/boot_tests/index_config_not_exists_malformed_file_config/" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) + mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + "readonlyrest.yml") implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentManager) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/index_config_not_exists_malformed_file_config/") + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentManager) + val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should startWith("ROR settings are malformed") + failure.message shouldBe "Errors:\nfailed" } } - "index settings don't exist and file settings cannot be loaded" in { + "index settings don't exist and core cannot be loaded" in { val resourcePath = "/boot_tests/index_config_not_exists_bad_file_config/" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) - val coreFactory = mockFailedCoreFactory(mock[CoreFactory], s"${resourcePath}readonlyrest.yml") + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcePath + "readonlyrest.yml") implicit val systemContext: SystemContext = createSystemContext() val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentManager) @@ -348,15 +346,17 @@ class ReadonlyRestStartingTests mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) + val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + "readonlyrest.yml") + implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mockedIndexDocumentManager) + val readonlyRest = readonlyRestBoot(coreFactory, mockedIndexDocumentManager) val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings(resourcesPath) val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { case Left(failure) => - failure.message should startWith("Settings content is malformed.") + failure.message shouldBe "Errors:\nfailed" } } "index settings cannot be loaded" in { @@ -380,36 +380,21 @@ class ReadonlyRestStartingTests } "ROR SSL (in elasticsearch.yml) is tried to be used when XPack Security is enabled" in { implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") + val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") - val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() - - inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR SSL settings when XPack Security is enabled") - } + result should be (Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) } "ROR SSL (in readonlyrest.yml) is tried to be used when XPack Security is enabled" in { implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") + val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() - - inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR SSL settings when XPack Security is enabled") - } + result should be (Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) } "ROR FIPS SSL is tried to be used when XPack Security is enabled" in { implicit val systemContext: SystemContext = createSystemContext() - val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) - val esConfigBasedRorSettings = forceCreateEsConfigBasedRorSettings("/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - - val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() + val result = createEsConfigBasedRorSettings("/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - inside(result) { case Left(failure) => - failure.message should be("Cannot use ROR FIBS settings when XPack Security is enabled") - } + result should be(Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) } } } @@ -450,10 +435,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + | "auth_services_mocks": $configuredAuthServicesMocksJson |}""".stripMargin ) ) @@ -517,10 +502,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + | "auth_services_mocks": $configuredAuthServicesMocksJson |}""".stripMargin ) ) @@ -583,7 +568,7 @@ class ReadonlyRestStartingTests | "settings": "malformed_settings", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + | "auth_services_mocks": $configuredAuthServicesMocksJson |}""".stripMargin ) ) @@ -613,10 +598,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${testSettingsMalformed.raw}", + | "settings": "${escapeJava(testSettingsMalformed.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${testClock.instant().plusSeconds(100).toString}", - | "auth_services_mocks": "${escapeJava(configuredAuthServicesMocksJson)}" + | "auth_services_mocks": $configuredAuthServicesMocksJson |}""".stripMargin ) ) @@ -671,8 +656,8 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && - document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("600000") && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded } @@ -722,7 +707,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -791,7 +776,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("600000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -820,7 +805,7 @@ class ReadonlyRestStartingTests (config: IndexName.Full, id: String, document: Json) => config == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("300000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -875,7 +860,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -905,7 +890,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings2.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings2.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("120000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -958,10 +943,10 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.now(Right(circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin )))) @@ -992,10 +977,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin ) ) @@ -1025,10 +1010,10 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.now(Right(circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "200000", | "expiration_timestamp": "${expirationTimestamp2.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin )))) @@ -1056,10 +1041,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin ) ) @@ -1091,10 +1076,10 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.now(Right(circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp2.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin )))) @@ -1122,10 +1107,10 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager, circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings2.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin ) ) @@ -1157,10 +1142,10 @@ class ReadonlyRestStartingTests .repeated(1) .returns(Task.delay(Right(circeJsonFrom( s"""{ - | "settings": "${escapeJava(testSettings2.raw)}", + | "settings": "${escapeJava(testSettings2.rawYaml)}", | "expiration_ttl_millis": "200000", | "expiration_timestamp": "${expirationTimestamp2.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |}""".stripMargin )))) @@ -1206,8 +1191,8 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && - document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && + document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("3000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded } @@ -1257,7 +1242,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -1280,7 +1265,7 @@ class ReadonlyRestStartingTests (config: IndexName.Full, id: String, document: Json) => config == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("60000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -1310,10 +1295,10 @@ class ReadonlyRestStartingTests circeJsonFrom( s""" |{ - | "settings": "${escapeJava(testSettings1.raw)}", + | "settings": "${escapeJava(testSettings1.rawYaml)}", | "expiration_ttl_millis": "100000", | "expiration_timestamp": "${expirationTimestamp.toString}", - | "auth_services_mocks": "${escapeJava(notConfiguredAuthServicesMocksJson)}" + | "auth_services_mocks": $notConfiguredAuthServicesMocksJson |} |""".stripMargin ) @@ -1347,7 +1332,7 @@ class ReadonlyRestStartingTests (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(".readonlyrest") && id == "2" && - document.hcursor.get[String]("settings").toOption.contains(testSettings1.raw) && + document.hcursor.get[String]("settings").toOption.contains(testSettings1.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("100000") && document.hcursor.get[String]("expiration_timestamp").toOption.exists(_ != expirationTimestamp.toString) } @@ -1510,13 +1495,13 @@ class ReadonlyRestStartingTests } private def mockCoreFactory(mockedCoreFactory: CoreFactory, - loaededMainSettingsResourceFileName: String, + loadedMainSettingsResourceFileName: String, accessControlMock: AccessControlList = mockEnabledAccessControl, dependencies: RorDependencies = RorDependencies.noOp, auditingSettings: Option[AuditingTool.Settings] = None): CoreFactory = { mockCoreFactory( mockedCoreFactory, - rorSettingsFromResource(loaededMainSettingsResourceFileName), + rorSettingsFromResource(loadedMainSettingsResourceFileName), accessControlMock, dependencies, auditingSettings diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala index fdbd4fc9fb..e2bf308c9a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala @@ -212,7 +212,7 @@ class RorIndexTest extends AnyWordSpec (indexDocumentManager.documentAsJson _) .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId) .once() - .returns(Task.now(Right(circeJsonFrom(s"""{ "settings": "${escapeJava(indexRorSettings.raw)}" }""")))) + .returns(Task.now(Right(circeJsonFrom(s"""{ "settings": "${escapeJava(indexRorSettings.rawYaml)}" }""")))) } private def mockInIndexTestSettingsLoading(indexDocumentManager: IndexDocumentManager, @@ -226,7 +226,7 @@ class RorIndexTest extends AnyWordSpec private def mockInIndexMainSettingsSaving(indexDocumentManager: IndexDocumentManager, indexName: NonEmptyString) = { (indexDocumentManager.saveDocumentJson _) - .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId, circeJsonFrom(s"""{ "settings": "${escapeJava(rorSettings.raw)}"}""")) + .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId, circeJsonFrom(s"""{ "settings": "${escapeJava(rorSettings.rawYaml)}"}""")) .once() .returns(Task.now(Right(()))) } @@ -239,7 +239,7 @@ class RorIndexTest extends AnyWordSpec (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(indexName) && id == testInIndexRorSettingsDocumentId && - document.hcursor.get[String]("settings").toOption.contains(rorSettings.raw) && + document.hcursor.get[String]("settings").toOption.contains(rorSettings.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("300000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala index ab0d25b42f..1bcd3f1264 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala @@ -163,7 +163,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { val result = rorSettingFrom(rawConfig) inside(result) { - case Right(config) => config.raw shouldBe rawConfig + case Right(config) => config.rawYaml shouldBe rawConfig } } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala index 03f4ba1d64..5ef154b663 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala @@ -79,7 +79,7 @@ class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject @@ -89,7 +89,7 @@ class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } From 8ebbe25a4e8784f4d47fb9962aa02a2689caf3b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 1 Oct 2025 11:55:14 +0200 Subject: [PATCH 035/103] refactoring --- .../accesscontrol/factory/CoreFactory.scala | 2 +- .../tech/beshu/ror/api/MainSettingsApi.scala | 9 +- .../tech/beshu/ror/api/TestSettingsApi.scala | 3 +- .../tech/beshu/ror/boot/ReadonlyRest.scala | 16 +- .../tech/beshu/ror/boot/RorInstance.scala | 42 +-- .../SecurityProviderConfiguratorForFips.scala | 4 +- .../SettingsRelatedCreatorsAndLoaders.scala | 23 +- .../boot/engines/BaseReloadableEngine.scala | 9 +- .../MainSettingsBasedReloadableEngine.scala | 11 +- .../beshu/ror/boot/engines/SettingsHash.scala | 2 +- .../TestSettingsBasedReloadableEngine.scala | 17 +- ...ServiceBasedIndexMainSettingsManager.scala | 77 ------ ...ServiceBasedIndexTestSettingsManager.scala | 256 ------------------ .../index/IndexSettingsManager.scala | 53 ---- .../loader/FileRorSettingsLoader.scala | 62 ----- .../loader/RorSettingsLoader.scala | 44 --- .../manager/FileSettingsManager.scala | 36 --- .../manager/InIndexSettingsManager.scala | 43 --- .../manager/RorMainSettingsManager.scala | 182 ------------- .../manager/RorTestSettingsManager.scala | 95 ------- .../main/scala/tech/beshu/ror/implicits.scala | 84 ++++-- .../es}/EsConfigBasedRorSettings.scala | 85 ++++-- .../es}/RorBootSettings.scala | 4 +- .../es}/RorProperties.scala | 59 +--- .../es}/RorSslSettings.scala | 6 +- .../es}/YamlFileBasedSettingsLoader.scala | 4 +- .../ForceLoadRorSettingsFromFileLoader.scala | 46 ---- ...hFileSourceFallbackRorSettingsLoader.scala | 83 ------ .../ror}/MainRorSettings.scala | 3 +- .../ror}/RawRorSettings.scala | 2 +- .../ror}/RawRorSettingsYamlParser.scala | 14 +- .../ror}/TestRorSettings.scala | 4 +- .../ForceLoadRorSettingsFromFileLoader.scala} | 22 +- .../{ => ror}/loader/RetryStrategy.scala | 15 +- ...hFileSourceFallbackRorSettingsLoader.scala | 64 +++++ .../loader/StartingRorSettingsLoader.scala | 47 ++++ .../{ => ror}/source/FileSettingsSource.scala | 15 +- .../source/IndexSettingsSource.scala | 22 +- .../source/MainSettingsFileSource.scala | 4 +- .../source/MainSettingsIndexSource.scala | 6 +- .../source/RawRorSettingsCodec.scala | 5 +- .../{ => ror}/source/SettingsSource.scala | 16 +- .../source/TestSettingsIndexSource.scala | 8 +- .../tech/beshu/ror/utils/SSLCertHelper.scala | 8 +- .../scala/tech/beshu/ror/utils/ScalaOps.scala | 4 + .../BaseYamlLoadedAccessControlTest.scala | 4 +- .../unit/acl/factory/AuditSettingsTests.scala | 2 +- .../unit/acl/factory/CoreFactoryTests.scala | 2 +- .../factory/ImpersonationWarningsTests.scala | 2 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 2 +- ... => IndexSettingsRelatedRorCoreTest.scala} | 6 +- .../unit/boot/ReadonlyRestStartingTests.scala | 9 +- .../configuration/RorBootSettingsTest.scala | 4 +- .../configuration/SslConfigurationTest.scala | 6 +- .../YamlFileBasedRorSettingsLoaderTest.scala | 2 +- .../tech/beshu/ror/utils/TestsUtils.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 6 +- .../rrconfig/rest/RestRRConfigAction.scala | 2 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 2 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 2 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 2 +- .../ror/es/actions/rrconfig/RRConfig.java | 4 +- .../es/actions/rrconfig/RRConfigRequest.java | 4 +- .../es/actions/rrconfig/RRConfigsRequest.java | 4 +- .../rrconfig/TransportRRConfigAction.scala | 4 +- .../rrconfig/rest/RestRRConfigAction.scala | 4 +- .../RestRRConfigActionResponseBuilder.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 2 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 4 +- .../RorNotAvailableRequestHandler.scala | 4 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- 391 files changed, 957 insertions(+), 1790 deletions(-) delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala rename core/src/main/scala/tech/beshu/ror/{configuration => settings/es}/EsConfigBasedRorSettings.scala (70%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/es}/RorBootSettings.scala (96%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/es}/RorProperties.scala (74%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/es}/RorSslSettings.scala (98%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/es}/YamlFileBasedSettingsLoader.scala (98%) delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala delete mode 100644 core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala rename core/src/main/scala/tech/beshu/ror/{configuration => settings/ror}/MainRorSettings.scala (95%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/ror}/RawRorSettings.scala (96%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/ror}/RawRorSettingsYamlParser.scala (75%) rename core/src/main/scala/tech/beshu/ror/{configuration => settings/ror}/TestRorSettings.scala (92%) rename core/src/main/scala/tech/beshu/ror/settings/{loader/StartingRorSettingsLoader.scala => ror/loader/ForceLoadRorSettingsFromFileLoader.scala} (50%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/loader/RetryStrategy.scala (81%) create mode 100644 core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/FileSettingsSource.scala (77%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/IndexSettingsSource.scala (76%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/MainSettingsFileSource.scala (91%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/MainSettingsIndexSource.scala (90%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/RawRorSettingsCodec.scala (88%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/SettingsSource.scala (72%) rename core/src/main/scala/tech/beshu/ror/settings/{ => ror}/source/TestSettingsIndexSource.scala (97%) rename core/src/test/scala/tech/beshu/ror/unit/boot/{RorIndexTest.scala => IndexSettingsRelatedRorCoreTest.scala} (98%) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index 2ed8dae92f..0477dbed43 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -50,7 +50,7 @@ import tech.beshu.ror.accesscontrol.factory.decoders.{AuditingSettingsDecoder, G import tech.beshu.ror.accesscontrol.utils.* import tech.beshu.ror.accesscontrol.utils.CirceOps.* import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers.FieldListResult.{FieldListValue, NoField} -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.es.EsVersion import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* diff --git a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala index 2dec3561ce..d6947c233a 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala @@ -29,10 +29,11 @@ import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} -import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.IndexNotFound -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError -import tech.beshu.ror.settings.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.LoadingError.IndexNotFound +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps class MainSettingsApi(rorInstance: RorInstance, diff --git a/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala index 872b9cf568..3e2c8672ca 100644 --- a/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/TestSettingsApi.scala @@ -28,7 +28,8 @@ import tech.beshu.ror.api.TestSettingsApi.{TestSettingsRequest, TestSettingsResp import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, RawSettingsReloadError, TestSettings} import tech.beshu.ror.boot.{RorInstance, RorSchedulers} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.{RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.CirceOps.toCirceErrorOps import tech.beshu.ror.utils.DurationOps.* diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index 36696058b0..b5098e6797 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.boot -import cats.Show import cats.data.{EitherT, NonEmptyList} import monix.eval.Task import monix.execution.Scheduler @@ -34,9 +33,10 @@ import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreC import tech.beshu.ror.accesscontrol.factory.{AsyncHttpClientsFactory, Core, CoreFactory, RawRorSettingsBasedCoreFactory} import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.* -import tech.beshu.ror.configuration.* import tech.beshu.ror.es.{EsEnv, IndexDocumentManager} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.* +import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant @@ -53,7 +53,7 @@ class ReadonlyRest(coreFactory: CoreFactory, def start(esConfigBasedRorSettings: EsConfigBasedRorSettings): Task[Either[StartingFailure, RorInstance]] = { (for { creatorsAndLoaders <- lift(SettingsRelatedCreatorsAndLoaders.create(esConfigBasedRorSettings, indexDocumentManager)) - loadedSettings <- EitherT(creatorsAndLoaders.startingRorSettingsLoader.load()) + loadedSettings <- EitherT(creatorsAndLoaders.startingRorSettingsLoader.load()).leftMap(StartingFailure(_)) (loadedMainRorSettings, loadedTestRorSettings) = loadedSettings instance <- startRor(esConfigBasedRorSettings, creatorsAndLoaders.creators, loadedMainRorSettings, loadedTestRorSettings) } yield instance).value @@ -204,13 +204,6 @@ class ReadonlyRest(coreFactory: CoreFactory, object ReadonlyRest { - // todo: move somewhere else - final case class StartingFailure(message: String, throwable: Option[Throwable] = None) - object StartingFailure { - // todo: move? - implicit val show: Show[StartingFailure] = Show.show(_.message) - } - final case class MainEngine(engine: Engine, settings: RawRorSettings) @@ -242,7 +235,8 @@ object ReadonlyRest { } } - // todo: do we need both? + final case class StartingFailure(message: String, throwable: Option[Throwable] = None) + def create(indexContentService: IndexDocumentManager, auditSinkServiceCreator: AuditSinkServiceCreator, env: EsEnv) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 4abf3174a5..4ae8fd9283 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -23,25 +23,25 @@ import cats.syntax.either.* import monix.catnap.Semaphore import monix.eval.Task import monix.execution.{Cancelable, Scheduler} - -import java.util.concurrent.atomic.AtomicReference import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.RorProperties.RefreshInterval -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, MainRorSettings, RawRorSettings} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.{CoreRefreshSettings, LoadingRorCoreStrategy} +import tech.beshu.ror.settings.ror.source.IndexSettingsSource +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant +import java.util.concurrent.atomic.AtomicReference class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, @@ -55,17 +55,17 @@ class RorInstance private(boot: ReadonlyRest, scheduler: Scheduler) extends Logging { - import creators.* import RorInstance.* import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} + import creators.* logger.info("ReadonlyREST was loaded ...") private val reloadTaskState: AtomicReference[ReloadTaskState] = new AtomicReference(ReloadTaskState.NotInitiated) mode match { - case Mode.WithPeriodicIndexCheck(RefreshInterval.Enabled(interval)) => + case Mode.WithPeriodicIndexCheck(interval) => scheduleEnginesReload(interval) - case Mode.WithPeriodicIndexCheck(RefreshInterval.Disabled) | Mode.NoPeriodicIndexCheck => + case Mode.NoPeriodicIndexCheck => logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") } @@ -248,10 +248,7 @@ object RorInstance { testEngine: ReadonlyRest.TestEngine) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - val mode = esConfigBasedRorSettings.loadingRorCoreStrategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters) => Mode.WithPeriodicIndexCheck(parameters.refreshInterval) - } + val mode = modeFrom(esConfigBasedRorSettings.loadingRorCoreStrategy) createInstance(boot, esConfigBasedRorSettings, creators, mode, mainEngine, testEngine) } @@ -278,9 +275,20 @@ object RorInstance { ) } + private def modeFrom(strategy: LoadingRorCoreStrategy) = { + strategy match { + case LoadingRorCoreStrategy.ForceLoadingFromFile => + Mode.NoPeriodicIndexCheck + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => + Mode.NoPeriodicIndexCheck + case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Enabled(refreshInterval)) => + Mode.WithPeriodicIndexCheck(refreshInterval) + } + } + sealed trait RawSettingsReloadError object RawSettingsReloadError { - final case class ReloadingFailed(failure: ReadonlyRest.StartingFailure) extends RawSettingsReloadError + final case class ReloadingFailed(failure: StartingFailure) extends RawSettingsReloadError final case class SettingsUpToDate(settings: RawRorSettings) extends RawSettingsReloadError object RorInstanceStopped extends RawSettingsReloadError } @@ -328,7 +336,7 @@ object RorInstance { private sealed trait Mode private object Mode { - final case class WithPeriodicIndexCheck(reloadInterval: RefreshInterval) extends Mode + final case class WithPeriodicIndexCheck(reloadInterval: PositiveFiniteDuration) extends Mode case object NoPeriodicIndexCheck extends Mode } diff --git a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala index 6d93347780..f0c657999c 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala @@ -18,8 +18,8 @@ package tech.beshu.ror.boot import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider -import tech.beshu.ror.configuration.RorSslSettings -import tech.beshu.ror.configuration.SslConfiguration.FipsMode.{NonFips, SslOnly} +import tech.beshu.ror.settings.es.RorSslSettings +import tech.beshu.ror.settings.es.SslConfiguration.FipsMode.{NonFips, SslOnly} import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import java.security.Security diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index a6915304b1..380b8a45ff 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -18,20 +18,16 @@ package tech.beshu.ror.boot import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} -import tech.beshu.ror.settings.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser +import tech.beshu.ror.settings.ror.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} +import tech.beshu.ror.settings.ror.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} final class SettingsRelatedCreatorsAndLoaders private(val startingRorSettingsLoader: StartingRorSettingsLoader, val creators: SettingsRelatedCreators) -final class SettingsRelatedCreators(val mainSettingsBasedReloadableEngineCreator: MainSettingsBasedReloadableEngine.Creator, - val mainSettingsApiCreator: MainSettingsApi.Creator, - val testSettingsBasedReloadableEngineCreator: TestSettingsBasedReloadableEngine.Creator, - val testSettingsApiCreator: TestSettingsApi.Creator) - object SettingsRelatedCreatorsAndLoaders { def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, @@ -49,10 +45,10 @@ object SettingsRelatedCreatorsAndLoaders { val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { case s@LoadingRorCoreStrategy.ForceLoadingFromFile => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) - case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(params) => + case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(retryStrategySettings, _) => new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader( mainSettingsIndexSource, - new ConfigurableRetryStrategy(params), + new ConfigurableRetryStrategy(retryStrategySettings), mainSettingsFileSource, testSettingsIndexSource ) @@ -68,3 +64,8 @@ object SettingsRelatedCreatorsAndLoaders { ) } } + +final class SettingsRelatedCreators(val mainSettingsBasedReloadableEngineCreator: MainSettingsBasedReloadableEngine.Creator, + val mainSettingsApiCreator: MainSettingsApi.Creator, + val testSettingsBasedReloadableEngineCreator: TestSettingsBasedReloadableEngine.Creator, + val testSettingsApiCreator: TestSettingsApi.Creator) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index c466a3bb98..d3da403ac1 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -26,13 +26,14 @@ import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RequestId import tech.beshu.ror.boot.ReadonlyRest -import tech.beshu.ror.boot.ReadonlyRest.Engine +import tech.beshu.ror.boot.ReadonlyRest.{Engine, StartingFailure} import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError import tech.beshu.ror.boot.engines.BaseReloadableEngine.* import tech.beshu.ror.boot.engines.BaseReloadableEngine.EngineState.NotStartedYet -import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.boot.engines.SettingsHash.toSettingsHash import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.utils.DurationOps.* import java.time.Instant @@ -373,7 +374,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, } newEngineState match { case _: EngineState.NotStartedYet => - Left(RawSettingsReloadError.ReloadingFailed(ReadonlyRest.StartingFailure("Cannot update engine TTL because engine was invalidated"))) + Left(RawSettingsReloadError.ReloadingFailed(StartingFailure("Cannot update engine TTL because engine was invalidated"))) case EngineState.Working(engineWithSetting, _) => Right(ReloadResult(engineWithSetting.engine, engineWithSetting.expiration.get)) case EngineState.Stopped => diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index 03c9420cad..d9d7ee2bc3 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -28,12 +28,13 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.RorInstance.RawSettingsReloadError.{ReloadingFailed, RorInstanceStopped, SettingsUpToDate} import tech.beshu.ror.boot.engines.BaseReloadableEngine.InitialEngine -import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, MainRorSettings} +import tech.beshu.ror.boot.engines.SettingsHash.toSettingsHash import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError -import tech.beshu.ror.settings.source.{IndexSettingsSource, MainSettingsIndexSource} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.ror.MainRorSettings +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.{IndexSettingsSource, MainSettingsIndexSource} import tech.beshu.ror.utils.ScalaOps.value private[boot] class MainSettingsBasedReloadableEngine private(boot: ReadonlyRest, diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala index 856634f024..4d84589139 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/SettingsHash.scala @@ -16,7 +16,7 @@ */ package tech.beshu.ror.boot.engines -import tech.beshu.ror.configuration.RawRorSettings +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.utils.Hasher import scala.language.implicitConversions diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 182e11ad44..771dba6a52 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -29,15 +29,16 @@ import tech.beshu.ror.boot.RorInstance.* import tech.beshu.ror.boot.RorInstance.IndexSettingsReloadWithUpdateError.{IndexSettingsSavingError, ReloadError} import tech.beshu.ror.boot.engines.BaseReloadableEngine.{EngineExpiration, EngineState, InitialEngine} import tech.beshu.ror.boot.engines.SettingsHash.* -import tech.beshu.ror.configuration.TestRorSettings.Expiration -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, TestRorSettings} import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.source.{IndexSettingsSource, TestSettingsIndexSource} -import tech.beshu.ror.settings.source.IndexSettingsSource.{LoadingError, SavingError} -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.ror.TestRorSettings.Expiration +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.{LoadingError, SavingError} +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.{IndexSettingsSource, TestSettingsIndexSource} +import tech.beshu.ror.settings.ror.{RawRorSettings, TestRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import tech.beshu.ror.utils.ScalaOps.value diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala deleted file mode 100644 index bd4efa34d8..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexMainSettingsManager.scala +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.index -// -//import monix.eval.Task -//import org.apache.logging.log4j.scala.Logging -//import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -//import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexMainSettingsManager.Const -//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -//import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.* -//import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.ParsingError -//import tech.beshu.ror.es.IndexJsonContentService -//import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -// -//final class IndexJsonContentServiceBasedIndexMainSettingsManager(override val settingsIndex: RorSettingsIndex, -// override val rorSettingsYamlParser: RawRorSettingsYamlParser, -// indexJsonContentService: IndexJsonContentService) -// extends IndexSettingsManager[RawRorSettings] -// with Logging { -// -// override def load(): Task[Either[Error[LoadingIndexSettingsError], RawRorSettings]] = { -// indexJsonContentService -// .sourceOf(settingsIndex.index, Const.id) -// .flatMap { -// case Right(source) => -// source -// .find(_._1 == Const.settingsKey) -// .map { case (_, rorYamlString) => -// rorSettingsYamlParser -// .fromString(rorYamlString) -// .map(_.left.map(ParsingError.apply)) -// } -// .getOrElse { -// settingsLoaderError(UnknownStructureOfIndexDocument) -// } -// case Left(CannotReachContentSource) => -// settingsLoaderError(IndexNotExist) -// case Left(ContentNotFound) => -// settingsLoaderError(IndexNotExist) -// } -// } -// -// override def save(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { -// indexJsonContentService -// .saveContent( -// settingsIndex.index, -// Const.id, -// Map(Const.settingsKey -> settings.raw) -// ) -// .map { -// _.left.map { case CannotWriteToIndex => CannotSaveSettings } -// } -// } -//} -//object IndexJsonContentServiceBasedIndexMainSettingsManager { -// private [IndexJsonContentServiceBasedIndexMainSettingsManager] object Const { -// val id = "1" -// val settingsKey = "settings" -// } -//} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala deleted file mode 100644 index 98d166da2f..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexJsonContentServiceBasedIndexTestSettingsManager.scala +++ /dev/null @@ -1,256 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.index -// -//import cats.data.EitherT -//import cats.implicits.* -//import eu.timepit.refined.types.string.NonEmptyString -//import io.circe.syntax.EncoderOps -//import io.circe.{Codec, Decoder, Encoder} -//import monix.eval.Task -//import org.apache.logging.log4j.scala.Logging -//import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.LdapService -//import tech.beshu.ror.accesscontrol.blocks.definitions.{ExternalAuthenticationService, ExternalAuthorizationService} -//import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks -//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthenticationServiceMock.ExternalAuthenticationUserMock -//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.ExternalAuthorizationServiceMock.ExternalAuthorizationServiceUserMock -//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.LdapUserMock -//import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} -//import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId -//import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} -//import tech.beshu.ror.configuration.TestRorSettings.Present -//import tech.beshu.ror.configuration.index.IndexJsonContentServiceBasedIndexTestSettingsManager.Const -//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError.{IndexNotExist, UnknownStructureOfIndexDocument} -//import tech.beshu.ror.configuration.index.IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -//import tech.beshu.ror.configuration.loader.RorSettingsLoader -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -//import tech.beshu.ror.configuration.{RawRorSettingsYamlParser, TestRorSettings} -//import tech.beshu.ror.es.IndexJsonContentService -//import tech.beshu.ror.es.IndexJsonContentService.{CannotReachContentSource, CannotWriteToIndex, ContentNotFound} -//import tech.beshu.ror.syntax.* -//import tech.beshu.ror.utils.DurationOps.* -//import tech.beshu.ror.utils.json.KeyCodec -// -//import java.time.format.DateTimeFormatter -//import java.time.{Instant, ZoneOffset} -//import scala.concurrent.duration.Duration -//import scala.util.Try -// -//final class IndexJsonContentServiceBasedIndexTestSettingsManager(override val settingsIndex: RorSettingsIndex, -// override val rorSettingsYamlParser: RawRorSettingsYamlParser, -// indexJsonContentService: IndexJsonContentService) -// extends IndexSettingsManager[TestRorSettings] -// with Logging { -// -// type Error = RorSettingsLoader.Error[LoadingIndexSettingsError] -// -// override def load(): Task[Either[Error, TestRorSettings]] = { -// indexJsonContentService -// .sourceOf(settingsIndex.index, Const.id) -// .flatMap { -// case Right(source) => -// val properties = source.collect { case (key: String, value: String) => (key, value) } -// getSettings(properties).value -// case Left(CannotReachContentSource) => -// settingsLoaderError(IndexNotExist) -// case Left(ContentNotFound) => -// Task.now(Right(TestRorSettings.NotSet)) -// } -// } -// -// override def save(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { -// indexJsonContentService -// .saveContent(settingsIndex.index, Const.id, formatSettings(settings)) -// .map { -// _.left.map { case CannotWriteToIndex => CannotSaveSettings } -// } -// } -// -// private def getSettings(config: Map[String, String]): EitherT[Task, Error, TestRorSettings] = { -// if (config.isEmpty) { -// EitherT.right[Error](Task.now(TestRorSettings.NotSet)).widen[TestRorSettings] -// } else { -// for { -// expirationTimeString <- getConfigProperty(config, Const.properties.expirationTime) -// expirationTtlString <- getConfigProperty(config, Const.properties.expirationTtl) -// rawRorConfigString <- getConfigProperty(config, Const.properties.settings) -// authMocksConfigString <- getConfigProperty(config, Const.properties.mocks) -// rawRorConfig <- EitherT { -// rorSettingsYamlParser -// .fromString(rawRorConfigString) -// .map(_.left.map(ParsingError.apply)) -// } -// expirationTime <- getInstant(expirationTimeString) -// expirationTtl <- getExpirationTtl(expirationTtlString) -// mocks <- getMocks(authMocksConfigString) -// } yield Present( -// rawSettings = rawRorConfig, -// mocks = mocks, -// expiration = Present.Expiration(ttl = expirationTtl, validTo = expirationTime) -// ) -// } -// } -// -// private def formatSettings(config: TestRorSettings): Map[String, String] = { -// config match { -// case TestRorSettings.NotSet => -// Map.empty -// case Present(rawConfig, mocks, expiration) => -// Map( -// Const.properties.expirationTime -> expiration.validTo.atOffset(ZoneOffset.UTC).toString, -// Const.properties.expirationTtl -> expiration.ttl.value.toMillis.toString, -// Const.properties.mocks -> formatMocks(mocks), -// Const.properties.settings -> rawConfig.raw -// ) -// } -// } -// -// private def getExpirationTtl(value: String): EitherT[Task, Error, PositiveFiniteDuration] = { -// Try { -// Duration -// .apply(value.toLong, "ms") -// .toRefinedPositive -// .leftMap((_: String) => parserError) -// } -// .toEither -// .leftMap(_ => parserError) -// .flatten -// .toEitherT[Task] -// } -// -// private def parserError: Error = -// SpecializedError[LoadingIndexSettingsError](UnknownStructureOfIndexDocument) -// -// private def getInstant(value: String): EitherT[Task, Error, Instant] = { -// Try(DateTimeFormatter.ISO_DATE_TIME.parse(value)) -// .map(Instant.from) -// .toEither -// .toEitherT[Task] -// .leftMap(_ => parserError) -// } -// -// private def formatMocks(mocks: AuthServicesMocks): String = { -// mocks.asJson.noSpaces -// } -// -// private def getMocks(config: String): EitherT[Task, Error, AuthServicesMocks] = { -// io.circe.parser.decode[AuthServicesMocks](config) -// .leftMap(_ => parserError) -// .toEitherT[Task] -// } -// -// private implicit val mocksCodec: Codec[AuthServicesMocks] = { -// implicit val nonEmptyStringCodec: Codec[NonEmptyString] = -// Codec.from(Decoder.decodeString.emap(NonEmptyString.from), Encoder.encodeString.contramap(_.value)) -// implicit val userIdCodec: Codec[User.Id] = -// Codec.from(nonEmptyStringCodec.map(User.Id.apply), nonEmptyStringCodec.contramap(_.value)) -// implicit val groupIdCodec: Codec[GroupId] = -// Codec.from( -// nonEmptyStringCodec.map(GroupId.apply), -// nonEmptyStringCodec.contramap(_.value) -// ) -// -// implicit val groupCodec: Codec[Group] = { -// implicit val groupNameCodec: Codec[GroupName] = Codec.from( -// nonEmptyStringCodec.map(GroupName.apply), -// nonEmptyStringCodec.contramap(_.value) -// ) -// Codec.forProduct2("id", "name")(Group.apply)(group => (group.id, group.name)) -// } -// implicit val ldapServiceMock: Codec[LdapServiceMock] = { -// implicit val userMock: Codec[LdapUserMock] = { -// // "groups" left for backward compatibility -// val encoder: Encoder[LdapUserMock] = Encoder.forProduct3("id", "groups", "userGroups")( -// userMock => (userMock.id, userMock.groups.map(_.id), userMock.groups) -// ) -// val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => -// LdapUserMock(id, groupIds.map(Group.from).toCovariantSet) -// ) -// val decoder: Decoder[LdapUserMock] = Decoder.forProduct2("id", "userGroups")(LdapUserMock.apply) -// Codec.from(decoder.or(deprecatedFormatDecoder), encoder) -// } -// Codec.forProduct1("users")(LdapServiceMock.apply)(_.users) -// } -// -// implicit val extAuthenticationMock: Codec[ExternalAuthenticationServiceMock] = { -// implicit val userMock: Codec[ExternalAuthenticationUserMock] = -// Codec.forProduct1("id")(ExternalAuthenticationUserMock.apply)(_.id) -// Codec.forProduct1("users")(ExternalAuthenticationServiceMock.apply)(_.users) -// } -// -// implicit val extAuthorizationMock: Codec[ExternalAuthorizationServiceMock] = { -// implicit val userMock: Codec[ExternalAuthorizationServiceUserMock] = { -// // "groups" left for backward compatibility -// val encoder = Encoder.forProduct3("id", "groups", "userGroups")( -// (userMock: ExternalAuthorizationServiceUserMock) => (userMock.id, userMock.groups.map(_.id), userMock.groups) -// ) -// val deprecatedFormatDecoder = Decoder.forProduct2("id", "groups")((id: User.Id, groupIds: List[GroupId]) => -// ExternalAuthorizationServiceUserMock(id, groupIds.map(Group.from).toCovariantSet) -// ) -// val decoder = Decoder.forProduct2("id", "userGroups")(ExternalAuthorizationServiceUserMock.apply) -// Codec.from(decoder.or(deprecatedFormatDecoder), encoder) -// } -// Codec.forProduct1("users")(ExternalAuthorizationServiceMock.apply)(_.users) -// } -// -// implicit val ldapKeyCodec: KeyCodec[LdapService.Name] = KeyCodec.from[LdapService.Name]( -// NonEmptyString.unapply(_).map(LdapService.Name.apply), -// _.value.value -// ) -// -// implicit val externalAuthenticationKeyCodec: KeyCodec[ExternalAuthenticationService.Name] = -// KeyCodec.from[ExternalAuthenticationService.Name]( -// NonEmptyString.unapply(_).map(ExternalAuthenticationService.Name.apply), -// _.value.value -// ) -// -// implicit val externalAuthorizationKeyCodec: KeyCodec[ExternalAuthorizationService.Name] = -// KeyCodec.from[ExternalAuthorizationService.Name]( -// NonEmptyString.unapply(_).map(ExternalAuthorizationService.Name.apply), -// _.value.value -// ) -// -// Codec.forProduct3( -// "ldapMocks", -// "externalAuthenticationMocks", -// "externalAuthorizationMocks" -// )(AuthServicesMocks.apply)(e => (e.ldapMocks, e.externalAuthenticationServiceMocks, e.externalAuthorizationServiceMocks)) -// } -// -// private def getConfigProperty[A, B](map: Map[A, B], key: A): EitherT[Task, Error, B] = { -// map -// .get(key) -// .toRight(parserError) -// .toEitherT[Task] -// } -// -//} -// -//private object IndexJsonContentServiceBasedIndexTestSettingsManager { -// private [IndexJsonContentServiceBasedIndexTestSettingsManager] object Const { -// val id = "2" -// object properties { -// val settings = "settings" -// val expirationTtl = "expiration_ttl_millis" -// val expirationTime = "expiration_timestamp" -// val mocks = "auth_services_mocks" -// } -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala deleted file mode 100644 index eeb904fe20..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/index/IndexSettingsManager.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.index -// -//import monix.eval.Task -//import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -//import tech.beshu.ror.configuration.RawRorSettingsYamlParser -//import tech.beshu.ror.configuration.index.IndexSettingsManager.{LoadingIndexSettingsError, SavingIndexSettingsError} -//import tech.beshu.ror.configuration.loader.RorSettingsLoader -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.SpecializedError -// -//trait IndexSettingsManager[SETTINGS] { -// -// def settingsIndex: RorSettingsIndex -// -// def rorSettingsYamlParser: RawRorSettingsYamlParser -// -// def load(): Task[Either[RorSettingsLoader.Error[LoadingIndexSettingsError], SETTINGS]] -// -// def save(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] -// -// protected final def settingsLoaderError(error: LoadingIndexSettingsError): Task[Either[SpecializedError[LoadingIndexSettingsError], SETTINGS]] = -// Task.now(Left(SpecializedError[LoadingIndexSettingsError](error))) -//} -//object IndexSettingsManager { -// -// sealed trait LoadingIndexSettingsError -// object LoadingIndexSettingsError { -// case object IndexNotExist extends LoadingIndexSettingsError -// case object UnknownStructureOfIndexDocument extends LoadingIndexSettingsError -// } -// -// sealed trait SavingIndexSettingsError -// object SavingIndexSettingsError { -// case object CannotSaveSettings extends SavingIndexSettingsError -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala deleted file mode 100644 index 4b333f6e26..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/FileRorSettingsLoader.scala +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.loader -// -//import better.files.File -//import cats.Show -//import cats.data.EitherT -//import monix.eval.Task -//import tech.beshu.ror.configuration.loader.FileRorSettingsLoader.Error.FileNotExist -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -//import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} -// -//class FileRorSettingsLoader(rorSettingsFile: File, -// rawRorSettingsYamlParser: RawRorSettingsYamlParser) -// extends RorSettingsLoader[FileRorSettingsLoader.Error] { -// -// def settingsFile: File = rorSettingsFile -// -// override def load(): Task[Either[Error[FileRorSettingsLoader.Error], RawRorSettings]] = { -// val file = rorSettingsFile -// (for { -// _ <- checkIfFileExist(file) -// settings <- loadSettingsFromFile(file) -// } yield settings).value -// } -// -// private def checkIfFileExist(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], File] = -// EitherT.cond(file.exists, file, SpecializedError(FileNotExist(file))) -// -// private def loadSettingsFromFile(file: File): EitherT[Task, Error[FileRorSettingsLoader.Error], RawRorSettings] = { -// EitherT(rawRorSettingsYamlParser.fromFile(file).map(_.left.map(ParsingError.apply))) -// } -//} -// -//object FileRorSettingsLoader { -// -// sealed trait Error -// object Error { -// final case class FileNotExist(file: File) extends Error -// -// implicit val show: Show[Error] = Show.show { -// case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" -// } -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala deleted file mode 100644 index abaf26fd1a..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/loader/RorSettingsLoader.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.loader -// -//import cats.Show -//import monix.eval.Task -//import tech.beshu.ror.configuration.RawRorSettings -//import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError -// -//trait RorSettingsLoader[SPECIALIZED_ERROR] { -// -// def load(): Task[Either[RorSettingsLoader.Error[SPECIALIZED_ERROR], RawRorSettings]] -//} -// -//object RorSettingsLoader { -// -// sealed trait Error[+SPECIALIZED_ERROR] -// object Error { -// final case class ParsingError(error: ParsingRorSettingsError) extends Error[Nothing] -// final case class SpecializedError[ERROR](error: ERROR) extends Error[ERROR] -// -// implicit def show[E: Show]: Show[Error[E]] = Show.show { -// case ParsingError(error) => Show[ParsingRorSettingsError].show(error) -// case SpecializedError(error) => Show[E].show(error) -// } -// } -// -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala deleted file mode 100644 index cf6315fda6..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/FileSettingsManager.scala +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.manager -// -//import better.files.File -//import monix.eval.Task -//import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -// -//trait FileSettingsManager[SETTINGS] { -// -// def loadFromFile(): Task[Either[LoadingFromFileError, SETTINGS]] -//} -//object FileSettingsManager { -// -// sealed trait LoadingFromFileError -// object LoadingFromFileError { -// final case class FileParsingError(message: String) extends LoadingFromFileError -// final case class FileNotExist(file: File) extends LoadingFromFileError -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala deleted file mode 100644 index 279811e239..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/InIndexSettingsManager.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.manager -// -//import monix.eval.Task -//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -// -//trait InIndexSettingsManager[SETTINGS] { -// -// def loadFromIndex(): Task[Either[LoadingFromIndexError, SETTINGS]] -// -// def saveToIndex(settings: SETTINGS): Task[Either[SavingIndexSettingsError, Unit]] -//} -//object InIndexSettingsManager { -// -// sealed trait LoadingFromIndexError -// object LoadingFromIndexError { -// final case class IndexParsingError(message: String) extends LoadingFromIndexError -// case object IndexUnknownStructure extends LoadingFromIndexError -// case object IndexNotExist extends LoadingFromIndexError -// } -// -// sealed trait SavingIndexSettingsError -// object SavingIndexSettingsError { -// case object CannotSaveSettings extends SavingIndexSettingsError -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala deleted file mode 100644 index a9d005dc54..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorMainSettingsManager.scala +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.manager -// -//import cats.data.EitherT -//import cats.implicits.toShow -//import monix.eval.Task -//import org.apache.logging.log4j.scala.Logging -//import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -//import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval} -//import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexMainSettingsManager, IndexSettingsManager} -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -//import tech.beshu.ror.configuration.loader.{FileRorSettingsLoader, RorSettingsLoader} -//import tech.beshu.ror.configuration.manager.FileSettingsManager.LoadingFromFileError -//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -//import tech.beshu.ror.configuration.manager.RorMainSettingsManager.LoadingError -//import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings, RawRorSettingsYamlParser} -//import tech.beshu.ror.es.IndexJsonContentService -//import tech.beshu.ror.implicits.* -//import tech.beshu.ror.utils.ScalaOps.LoggerOps -// -//import scala.concurrent.duration.FiniteDuration -//import scala.language.postfixOps -// -//class RorMainSettingsManager private(esConfigBasedRorSettings: EsConfigBasedRorSettings, -// fileSettingsLoader: FileRorSettingsLoader, -// indexSettingsManager: IndexSettingsManager[RawRorSettings]) -// extends FileSettingsManager[RawRorSettings] -// with InIndexSettingsManager[RawRorSettings] -// with Logging { -// -// def loadAccordingToStrategy(): Task[Either[LoadingError, RawRorSettings]] = { -// def loadFromFileWithLoadingError(): Task[Either[LoadingError, RawRorSettings]] = -// loadFromFile().map(_.left.map(Left.apply)) -// -// esConfigBasedRorSettings.loadingRorCoreStrategy match { -// case LoadingRorCoreStrategy.ForceLoadingFromFile(parameters) => -// loadFromFileWithLoadingError() -// case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(parameters, fallbackParameters) => -// for { -// _ <- wait(parameters.loadingDelay.value.value) -// result <- attemptLoadingFromIndex( -// loadingAttemptsInterval = parameters.loadingAttemptsInterval, -// loadingAttemptsCount = parameters.loadingAttemptsCount, -// fallback = loadFromFileWithLoadingError() -// ) -// } yield result -// } -// } -// -// override def loadFromFile(): Task[Either[LoadingFromFileError, RawRorSettings]] = { -// val result = for { -// _ <- lift(logger.info(s"Loading ReadonlyREST settings from file: ${fileSettingsLoader.settingsFile.show}")) -// settings <- EitherT(fileSettingsLoader.load()) -// .leftMap(convertFileError) -// .leftSemiflatTap { error => -// logger.dError(s"Loading ReadonlyREST settings from file failed: ${error.toString}") -// } -// } yield settings -// result.value -// } -// -// override def loadFromIndex(): Task[Either[LoadingFromIndexError, RawRorSettings]] = { -// loadRorSettingsFromIndex() -// } -// -// override def saveToIndex(settings: RawRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { -// EitherT(indexSettingsManager.save(settings)) -// .leftMap { -// case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -// } -// .value -// } -// -// private def attemptLoadingFromIndex(loadingAttemptsInterval: LoadingAttemptsInterval, -// loadingAttemptsCount: LoadingAttemptsCount, -// fallback: Task[Either[LoadingError, RawRorSettings]]): Task[Either[LoadingError, RawRorSettings]] = { -// loadingAttemptsCount.value.value match { -// case 0 => -// fallback.map(identity) -// case attemptsCount => -// loadRorSettingsFromIndex() -// .flatMap { -// case Left(LoadingFromIndexError.IndexNotExist) => -// for { -// _ <- wait(loadingAttemptsInterval.value.value) -// result <- attemptLoadingFromIndex( -// loadingAttemptsInterval = loadingAttemptsInterval, -// loadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(loadingAttemptsCount.value.value - 1), -// fallback = fallback -// ) -// } yield result -// case Left(LoadingFromIndexError.IndexUnknownStructure) => -// Task.now(Left(Right(LoadingFromIndexError.IndexUnknownStructure))) -// case Left(error@LoadingFromIndexError.IndexParsingError(_)) => -// Task.now(Left(Right(error))) -// case Right(value) => -// Task.now(Right(value)) -// } -// } -// } -// -// private def loadRorSettingsFromIndex() = { -// val settingsIndex = indexSettingsManager.settingsIndex -// val result = for { -// _ <- lift(logger.info(s"Loading ReadonlyREST settings from index (${settingsIndex.index.show}) ...")) -// settings <- EitherT(indexSettingsManager.load()) -// .leftMap(convertIndexError) -// .biSemiflatTap( -// { -// case LoadingFromIndexError.IndexParsingError(message) => -// logger.dError(s"Loading ReadonlyREST settings from index failed: ${message.show}") -// case LoadingFromIndexError.IndexUnknownStructure => -// logger.dInfo(s"Loading ReadonlyREST settings from index failed: index content malformed") -// case LoadingFromIndexError.IndexNotExist => -// logger.dInfo(s"Loading ReadonlyREST settings from index failed: cannot find index") -// }, -// rorSettings => { -// logger.dDebug(s"Loaded ReadonlyREST settings from index: ${rorSettings.raw.show}") -// } -// ) -// } yield settings -// result.value -// } -// -// private def convertFileError(error: RorSettingsLoader.Error[FileRorSettingsLoader.Error]): LoadingFromFileError = { -// error match { -// case ParsingError(error) => LoadingFromFileError.FileParsingError(error.show) -// case SpecializedError(FileRorSettingsLoader.Error.FileNotExist(file)) => LoadingFromFileError.FileNotExist(file.path) -// } -// } -// -// private def convertIndexError(error: RorSettingsLoader.Error[IndexSettingsManager.LoadingIndexSettingsError]): LoadingFromIndexError = -// error match { -// case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) -// case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist -// case SpecializedError(IndexSettingsManager.LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure -// } -// -// private def wait(duration: FiniteDuration) = { -// Task.sleep(duration).map(Right.apply) -// } -// -// private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) -//} -// -//object RorMainSettingsManager { -// -// type LoadingError = Either[LoadingFromFileError, LoadingFromIndexError] -// -// def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, -// indexJsonContentService: IndexJsonContentService): RorMainSettingsManager = { -// val rorSettingsFile = esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsFile -// val yamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) -// new RorMainSettingsManager( -// esConfigBasedRorSettings, -// new FileRorSettingsLoader(rorSettingsFile, yamlParser), -// new IndexJsonContentServiceBasedIndexMainSettingsManager( -// esConfigBasedRorSettings.rorSettingsIndex, -// yamlParser, -// indexJsonContentService, -// ) -// ) -// } -// -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala b/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala deleted file mode 100644 index d03b4c750a..0000000000 --- a/core/src/main/scala/tech/beshu/ror/configuration/manager/RorTestSettingsManager.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -//package tech.beshu.ror.configuration.manager -// -//import cats.data.EitherT -//import monix.eval.Task -//import org.apache.logging.log4j.scala.Logging -//import tech.beshu.ror.configuration.index.IndexSettingsManager.LoadingIndexSettingsError -//import tech.beshu.ror.configuration.index.{IndexJsonContentServiceBasedIndexTestSettingsManager, IndexSettingsManager} -//import tech.beshu.ror.configuration.loader.RorSettingsLoader -//import tech.beshu.ror.configuration.loader.RorSettingsLoader.Error.{ParsingError, SpecializedError} -//import tech.beshu.ror.configuration.manager.InIndexSettingsManager.{LoadingFromIndexError, SavingIndexSettingsError} -//import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettingsYamlParser, TestRorSettings} -//import tech.beshu.ror.es.IndexJsonContentService -//import tech.beshu.ror.implicits.* -//import tech.beshu.ror.utils.ScalaOps.LoggerOps -// -//import scala.language.postfixOps -// -//class RorTestSettingsManager private(indexSettingsManager: IndexSettingsManager[TestRorSettings]) -// extends InIndexSettingsManager[TestRorSettings] -// with Logging { -// -// override def loadFromIndex(): Task[Either[LoadingFromIndexError, TestRorSettings]] = { -// val settingsIndex = indexSettingsManager.settingsIndex -// val result = for { -// _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index (${settingsIndex.index.show}) ...")) -// settings <- EitherT(indexSettingsManager.load()) -// .leftMap(convertIndexError) -// .biSemiflatTap( -// { -// case LoadingFromIndexError.IndexParsingError(message) => -// logger.dError(s"Loading ReadonlyREST test settings from index failed: ${message.show}") -// case LoadingFromIndexError.IndexUnknownStructure => -// logger.dInfo("Loading ReadonlyREST test settings from index failed: index content malformed") -// case LoadingFromIndexError.IndexNotExist => -// logger.dInfo("Loading ReadonlyREST test settings from index failed: cannot find index") -// }, -// { -// case TestRorSettings.Present(rawConfig, _, _) => -// logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${rawConfig.raw.show}") -// case TestRorSettings.NotSet => -// logger.dDebug("There was no ReadonlyREST test settings in the index. Test settings engine will be not initialized.") -// } -// ) -// } yield settings -// result.value -// } -// -// override def saveToIndex(settings: TestRorSettings): Task[Either[SavingIndexSettingsError, Unit]] = { -// EitherT(indexSettingsManager.save(settings)) -// .leftMap { -// case IndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings => InIndexSettingsManager.SavingIndexSettingsError.CannotSaveSettings -// } -// .value -// } -// -// private def convertIndexError(error: RorSettingsLoader.Error[LoadingIndexSettingsError]): LoadingFromIndexError = -// error match { -// case ParsingError(error) => LoadingFromIndexError.IndexParsingError(error.show) -// case SpecializedError(LoadingIndexSettingsError.IndexNotExist) => LoadingFromIndexError.IndexNotExist -// case SpecializedError(LoadingIndexSettingsError.UnknownStructureOfIndexDocument) => LoadingFromIndexError.IndexUnknownStructure -// } -// -// private def lift[A](value: => A) = EitherT(Task.delay(Right(value))) -//} -//object RorTestSettingsManager { -// -// def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, -// indexJsonContentService: IndexJsonContentService): RorTestSettingsManager = { -// new RorTestSettingsManager( -// new IndexJsonContentServiceBasedIndexTestSettingsManager( -// settingsIndex = esConfigBasedRorSettings.rorSettingsIndex, -// indexJsonContentService = indexJsonContentService, -// rorSettingsYamlParser = RawRorSettingsYamlParser(esConfigBasedRorSettings.loadingRorCoreStrategy.rorSettingsMaxSize) -// ) -// ) -// } -//} - -// todo: remove \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 4c58e700a8..f500d99ba2 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -57,9 +57,18 @@ import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError import tech.beshu.ror.accesscontrol.factory.BlockValidator.BlockValidationError.{KibanaRuleTogetherWith, KibanaUserDataRuleTogetherWith} import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.request.RequestContext -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError +import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.CoreRefreshSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.{FileSettingsSource, IndexSettingsSource} +import tech.beshu.ror.settings.ror.{MainRorSettings, TestRorSettings} import tech.beshu.ror.utils.ScalaOps.* import tech.beshu.ror.utils.json.JsonPath import tech.beshu.ror.utils.set.CovariantSet @@ -396,24 +405,57 @@ trait LogsShowInstances case AccessRequirement.MustBeAbsent(value) => s"~${value.show}" } - implicit val loadEsConfigErrorShow: Show[LoadingError] = Show.show { - case LoadingError.FileNotFound(file) => s"Cannot find elasticsearch settings file: [${file.show}]" - case LoadingError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" - case LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => s"Cannot use ROR SSL when XPack Security is enabled" - } -// todo: fixme -// implicit val loadingFromIndexErrorShow: Show[LoadingFromIndexError] = Show.show { -// case LoadingFromIndexError.IndexNotExist => "Cannot find ReadonlyREST settings index" -// case LoadingFromIndexError.IndexUnknownStructure => "Unknown structure of ReadonlyREST index settings document" -// case LoadingFromIndexError.IndexParsingError(message) => s"Cannot parse in-index ReadonlyREST settings. Cause: $message" -// } - -// implicit val loadingFromFileErrorShow: Show[LoadingFromFileError] = Show.show { -// case LoadingFromFileError.FileParsingError(message) => s"Cannot parse file ReadonlyREST settings. Cause: $message" -// case LoadingFromFileError.FileNotExist(file) => s"Cannot find ReadonlyREST settings file: ${file.pathAsString}" -// } -// -// implicit val savingIndexSettingsErrorShow: Show[SavingIndexSettingsError] = Show.show { -// case SavingIndexSettingsError.CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" -// } + implicit val coreRefreshSettingsShow: Show[CoreRefreshSettings] = Show.show { + case CoreRefreshSettings.Disabled => "0 sec" + case CoreRefreshSettings.Enabled(interval) => interval.value.toString() + } + + implicit val loadingDelayShow: Show[LoadingDelay] = Show[FiniteDuration].contramap(_.value.value) + + implicit val loadingAttemptsCountShow: Show[LoadingAttemptsCount] = Show[Int].contramap(_.value.value) + + implicit val loadingAttemptsIntervalShow: Show[LoadingAttemptsInterval] = Show[FiniteDuration].contramap(_.value.value) + + implicit val testRorSettingsShow: Show[TestRorSettings] = Show.show(_.rawSettings.rawYaml) + + implicit val mainRorSettingsShow: Show[MainRorSettings] = Show.show(_.rawSettings.rawYaml) + + implicit val esConfigBasedRorSettingsLoadingErrorShow: Show[EsConfigBasedRorSettings.LoadingError] = Show.show { + case EsConfigBasedRorSettings.LoadingError.FileNotFound(file) => + s"Cannot find elasticsearch settings file: [${file.show}]" + case EsConfigBasedRorSettings.LoadingError.MalformedContent(file, message) => + s"Settings file is malformed: [${file.show}], ${message.show}" + case EsConfigBasedRorSettings.LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => + s"Cannot use ROR SSL when XPack Security is enabled" + } + + implicit val parsingRorSettingsErrorShow: Show[ParsingRorSettingsError] = Show.show { + case NoRorSection => "Cannot find any 'readonlyrest' section in settings" + case MoreThanOneRorSection => "Only one 'readonlyrest' section is required" + case InvalidContent(ex) => s"Settings content is malformed. Details: ${ex.getMessage.show}" + } + + implicit val indexSettingsSourceLoadingErrorShow: Show[IndexSettingsSource.LoadingError] = Show.show { + case IndexSettingsSource.LoadingError.IndexNotFound => "cannot find ReadonlyREST settings index" + case IndexSettingsSource.LoadingError.DocumentNotFound => "cannot found document with ReadonlyREST settings" + } + + implicit val indexSettingsSourceSavingErrorShow: Show[IndexSettingsSource.SavingError] = Show.show { + case IndexSettingsSource.SavingError.CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" + } + + implicit val fileSettingsSourceLoadingErrorShow: Show[FileSettingsSource.LoadingError] = Show.show { + case FileSettingsSource.LoadingError.FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" + } + + implicit val show: Show[StartingFailure] = Show.show(_.message) + + implicit def loadingSettingsErrorShow[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { + case LoadingSettingsError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" + case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + } + + implicit def savingSettingsErrorShow[ERROR: Show]: Show[SavingSettingsError[ERROR]] = Show.show { + case SavingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala similarity index 70% rename from core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index ffdc9fb43c..7c369b1417 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -14,10 +14,12 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.es import better.files.File import cats.data.{EitherT, NonEmptyList} +import eu.timepit.refined.api.Refined +import eu.timepit.refined.numeric.NonNegative import eu.timepit.refined.types.string.NonEmptyString import io.circe.Decoder import monix.eval.Task @@ -25,14 +27,16 @@ import squants.information.Information import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError.{CannotUseRorSslWhenXPackSecurityIsEnabled, FileNotFound, MalformedContent} -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.configuration.RorProperties.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay, RefreshInterval} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError.{CannotUseRorSslWhenXPackSecurityIsEnabled, FileNotFound, MalformedContent} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} import tech.beshu.ror.utils.yaml.YamlKeyDecoder -import scala.language.implicitConversions +import scala.concurrent.duration.{DurationInt, FiniteDuration} +import scala.language.{implicitConversions, postfixOps} final case class EsConfigBasedRorSettings(boot: RorBootSettings, ssl: Option[RorSslSettings], @@ -60,18 +64,18 @@ object EsConfigBasedRorSettings { } private def loadRorBootSettings(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { + (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, RorBootSettings] = { EitherT(RorBootSettings.load(esEnv)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } private def loadXpackSecuritySettings(esEnv: EsEnv, ossDistribution: Boolean) - (implicit systemContext: SystemContext) = { + (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, XpackSecuritySettings] = { EitherT { Task.delay { - implicit val xpackSettingsDecoder: Decoder[XpackSecurity] = decoders.xpackSettingsDecoder(ossDistribution) + implicit val xpackSettingsDecoder: Decoder[XpackSecuritySettings] = decoders.xpackSettingsDecoder(ossDistribution) new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) - .loadSettings[XpackSecurity](settingsName = "X-Pack settings") + .loadSettings[XpackSecuritySettings](settingsName = "X-Pack settings") .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) } } @@ -79,7 +83,7 @@ object EsConfigBasedRorSettings { private def loadRorSslSettings(esEnv: EsEnv, rorSettingsFile: RorSettingsFile, - xpackSecurity: XpackSecurity) + xpackSecurity: XpackSecuritySettings) (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { EitherT(RorSslSettings.load(rorSettingsFile, esEnv.elasticsearchYmlFile)) .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) @@ -130,16 +134,43 @@ object EsConfigBasedRorSettings { sealed trait LoadingRorCoreStrategy object LoadingRorCoreStrategy { case object ForceLoadingFromFile extends LoadingRorCoreStrategy - final case class LoadFromIndexWithFileFallback(parameters: LoadFromIndexParameters) // todo: what about retries? + final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, + coreRefreshSettings: CoreRefreshSettings) extends LoadingRorCoreStrategy } - final case class LoadFromIndexParameters(refreshInterval: RefreshInterval, - loadingAttemptsInterval: LoadingAttemptsInterval, - loadingAttemptsCount: LoadingAttemptsCount, - loadingDelay: LoadingDelay) // todo: rename to reload or sth? + final case class LoadingRetryStrategySettings(attemptsInterval: LoadingAttemptsInterval, + attemptsCount: LoadingAttemptsCount, + delay: LoadingDelay) + object LoadingRetryStrategySettings { + + final case class LoadingAttemptsCount(value: Int Refined NonNegative) extends AnyVal + object LoadingAttemptsCount { + def unsafeFrom(value: Int): LoadingAttemptsCount = LoadingAttemptsCount(Refined.unsafeApply(value)) - private final case class XpackSecurity(enabled: Boolean) + val zero: LoadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(0) + } + + final case class LoadingAttemptsInterval(value: NonNegativeFiniteDuration) extends AnyVal + object LoadingAttemptsInterval { + def unsafeFrom(value: FiniteDuration): LoadingAttemptsInterval = LoadingAttemptsInterval(value.toRefinedNonNegativeUnsafe) + } + + final case class LoadingDelay(value: NonNegativeFiniteDuration) extends AnyVal + object LoadingDelay { + val none: LoadingDelay = unsafeFrom(0 seconds) + + def unsafeFrom(value: FiniteDuration): LoadingDelay = LoadingDelay(value.toRefinedNonNegativeUnsafe) + } + } + + sealed trait CoreRefreshSettings + object CoreRefreshSettings { + case object Disabled extends CoreRefreshSettings + final case class Enabled(refreshInterval: PositiveFiniteDuration) extends CoreRefreshSettings + } + + private final case class XpackSecuritySettings(enabled: Boolean) sealed trait LoadingError object LoadingError { @@ -159,8 +190,11 @@ object EsConfigBasedRorSettings { Decoder.const(LoadingRorCoreStrategy.ForceLoadingFromFile) case false => for { - loadFromIndexSettings <- loadFromIndexSettingsDecoder(systemContext.propertiesProvider) - } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(loadFromIndexSettings) + loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) + coreRefreshIntervalSettings <- loadCoreRefreshSettings(systemContext.propertiesProvider) + } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback( + loadingRetryStrategySettings, coreRefreshIntervalSettings + ) } } @@ -190,9 +224,9 @@ object EsConfigBasedRorSettings { )) } - def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecurity] = { + def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecuritySettings] = { if (isOssDistribution) { - Decoder.const(XpackSecurity(enabled = false)) + Decoder.const(XpackSecuritySettings(enabled = false)) } else { val booleanDecoder = YamlKeyDecoder[Boolean]( path = NonEmptyList.of("xpack", "security", "enabled"), @@ -204,18 +238,16 @@ object EsConfigBasedRorSettings { ) map { _.toBoolean } - (booleanDecoder or stringDecoder) map XpackSecurity.apply + (booleanDecoder or stringDecoder) map XpackSecuritySettings.apply } } - private implicit def loadFromIndexSettingsDecoder(propertiesProvider: PropertiesProvider): Decoder[LoadFromIndexParameters] = { + private def loadLoadingRetryStrategySettings(propertiesProvider: PropertiesProvider): Decoder[LoadingRetryStrategySettings] = { for { - refreshInterval <- Decoder.instance(_ => Right(RorProperties.rorIndexSettingsReloadInterval(propertiesProvider))) loadingAttemptsInterval <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(propertiesProvider))) loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) - } yield LoadFromIndexParameters( - refreshInterval, + } yield LoadingRetryStrategySettings( loadingAttemptsInterval, loadingAttemptsCount, loadingDelay @@ -223,4 +255,7 @@ object EsConfigBasedRorSettings { } } + private def loadCoreRefreshSettings(propertiesProvider: PropertiesProvider): Decoder[CoreRefreshSettings] = { + Decoder.instance(_ => Right(RorProperties.rorCoreRefreshSettings(propertiesProvider))) + } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala similarity index 96% rename from core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala index 3ad7173c41..04278dc0ba 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorBootSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala @@ -14,15 +14,15 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.es import cats.data.NonEmptyList import io.circe.Decoder import monix.eval.Task import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.utils.yaml.YamlKeyDecoder final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala similarity index 74% rename from core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala index 4ab4c0c532..cbd5fbc337 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.es import better.files.File import cats.Show @@ -27,6 +27,8 @@ import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.providers.PropertiesProvider.PropName +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.CoreRefreshSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.RefinedUtils.* @@ -59,11 +61,11 @@ object RorProperties extends Logging { .getProperty(PropName(keys.rorSettingsFilePath)) .map(f => RorSettingsFile(File(f))) - def rorIndexSettingsReloadInterval(implicit propertiesProvider: PropertiesProvider): RefreshInterval = + def rorCoreRefreshSettings(implicit propertiesProvider: PropertiesProvider): CoreRefreshSettings = getProperty( keys.rorSettingsRefreshInterval, - str => toRefreshInterval(str), - RefreshInterval.Enabled(defaults.refreshInterval) + str => toCoreRefreshSettings(str), + CoreRefreshSettings.Enabled(defaults.refreshInterval) ) def atStartupRorIndexSettingsLoadingAttemptsInterval(implicit propertiesProvider: PropertiesProvider): LoadingAttemptsInterval = @@ -121,17 +123,19 @@ object RorProperties extends Logging { } } - private def toRefreshInterval(value: String): Try[RefreshInterval] = toPositiveFiniteDuration(value).map { - case Some(value) => RefreshInterval.Enabled(value) - case None => RefreshInterval.Disabled + private def toCoreRefreshSettings(value: String): Try[CoreRefreshSettings] = toPositiveFiniteDuration(value).map { + case Some(value) => CoreRefreshSettings.Enabled(value) + case None => CoreRefreshSettings.Disabled } private def toLoadingAttemptsInterval(value: String): Try[LoadingAttemptsInterval] = toNonNegativeFiniteDuration(value).map(LoadingAttemptsInterval.apply) - private def toLoadingDelay(value: String): Try[LoadingDelay] = toNonNegativeFiniteDuration(value).map(LoadingDelay.apply) + private def toLoadingDelay(value: String): Try[LoadingDelay] = + toNonNegativeFiniteDuration(value).map(LoadingDelay.apply) - private def toLoadingAttempts(value: String): Try[LoadingAttemptsCount] = toNonNegativeInt(value).map(LoadingAttemptsCount.apply) + private def toLoadingAttempts(value: String): Try[LoadingAttemptsCount] = + toNonNegativeInt(value).map(LoadingAttemptsCount.apply) private def toPositiveFiniteDuration(value: String): Try[Option[PositiveFiniteDuration]] = Try { durationFrom(value) match { @@ -157,41 +161,4 @@ object RorProperties extends Logging { case Success(_) | Failure(_) => throw new IllegalArgumentException(s"Cannot convert '${value.show}' to non-negative integer") } } - - final case class LoadingDelay(value: NonNegativeFiniteDuration) extends AnyVal - object LoadingDelay { - val none: LoadingDelay = unsafeFrom(0 seconds) - - def unsafeFrom(value: FiniteDuration): LoadingDelay = LoadingDelay(value.toRefinedNonNegativeUnsafe) - - implicit val show: Show[LoadingDelay] = Show[FiniteDuration].contramap(_.value.value) - } - - sealed trait RefreshInterval - object RefreshInterval { - case object Disabled extends RefreshInterval - - final case class Enabled(interval: PositiveFiniteDuration) extends RefreshInterval - - implicit val show: Show[RefreshInterval] = Show.show { - case Disabled => "0 sec" - case Enabled(interval) => interval.value.toString() - } - } - - final case class LoadingAttemptsCount(value: Int Refined NonNegative) extends AnyVal - object LoadingAttemptsCount { - def unsafeFrom(value: Int): LoadingAttemptsCount = LoadingAttemptsCount(Refined.unsafeApply(value)) - - val zero: LoadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(0) - - implicit val show: Show[LoadingAttemptsCount] = Show[Int].contramap(_.value.value) - } - - final case class LoadingAttemptsInterval(value: NonNegativeFiniteDuration) extends AnyVal - object LoadingAttemptsInterval { - def unsafeFrom(value: FiniteDuration): LoadingAttemptsInterval = LoadingAttemptsInterval(value.toRefinedNonNegativeUnsafe) - - implicit val show: Show[LoadingAttemptsInterval] = Show[FiniteDuration].contramap(_.value.value) - } } diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala similarity index 98% rename from core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index df97004b0c..288dfa8c87 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.es import better.files.* import io.circe.{Decoder, DecodingFailure, HCursor} @@ -23,8 +23,8 @@ import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers -import tech.beshu.ror.configuration.SslConfiguration.{ExternalSslSettings, FipsMode, InternodeSslSettings} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.SslConfiguration.* import tech.beshu.ror.utils.SSLCertHelper sealed trait RorSslSettings @@ -171,8 +171,6 @@ object SslConfiguration { private object SslDecoders extends Logging { - import tech.beshu.ror.configuration.SslConfiguration.* - object consts { val rorSection = "readonlyrest" val fipsMode = "fips_mode" diff --git a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala similarity index 98% rename from core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala index 6c293e5dec..403dc56b17 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/YamlFileBasedSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.es import better.files.File import io.circe.{Decoder, DecodingFailure, Json} @@ -22,8 +22,8 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.factory.JsonStaticVariablesResolver import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.yaml.YamlParser import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson +import tech.beshu.ror.utils.yaml.YamlParser final class YamlFileBasedSettingsLoader(file: File) (implicit systemContext: SystemContext) { diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala deleted file mode 100644 index d119310bbb..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/ForceLoadRorSettingsFromFileLoader.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.loader - -import cats.data.EitherT -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} -import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.FileSettingsSource -import tech.beshu.ror.utils.ScalaOps.* - -class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSource[MainRorSettings]) - extends StartingRorSettingsLoader with Logging { - - override def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] = { - val result = for { - _ <- lift(logger.info(s"Loading ReadonlyREST main settings from file: ${mainSettingsFileSource.settingsFile.show}")) - settings <- EitherT(mainSettingsFileSource.load()) - .biSemiflatTap( - error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file: ${settings.rawSettings.rawYaml.show}") - ) - .leftMap(error => StartingFailure(error.show)) - } yield (settings, None) - result.value - } - - private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) - -} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala deleted file mode 100644 index d89cb5d60c..0000000000 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.settings.loader - -import cats.data.EitherT -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} -import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.source.* -import tech.beshu.ror.utils.ScalaOps.* - -class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource: MainSettingsIndexSource, - mainSettingsIndexLadingRetryStrategy: RetryStrategy, - mainSettingsFileSource: MainSettingsFileSource, - testSettingsIndexSource: TestSettingsIndexSource) - extends StartingRorSettingsLoader with Logging { - - override def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] = { - loadMainSettingsFromIndex().orElse(loadMainSettingsFromFile()).value - val result = for { - mainSettings <- mainSettingsIndexLadingRetryStrategy - .withRetryT(loadMainSettingsFromIndex()) - .orElse(loadMainSettingsFromFile()) - testSettings <- loadTestSettingsFromIndex().recover { case failure => Option.empty[TestRorSettings] } - } yield (mainSettings, testSettings) - result.value - } - - private def loadMainSettingsFromIndex() = { - for { - _ <- lift(logger.info(s"Loading ReadonlyREST main settings from index: ${mainSettingsIndexSource.settingsIndex.show} ...")) - loadedSettings <- EitherT(mainSettingsIndexSource.load()) - .biSemiflatTap( - error => logger.dInfo(s"Loading ReadonlyREST main settings from index failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from index:\n${settings.rawSettings.rawYaml.show}") - ) - .leftMap(error => StartingFailure(error.show)) - } yield loadedSettings - } - - private def loadMainSettingsFromFile() = { - for { - _ <- lift(logger.info(s"Loading ReadonlyREST main settings from file: ${mainSettingsFileSource.settingsFile.show}")) - loadedSettings <- EitherT(mainSettingsFileSource.load()) - .biSemiflatTap( - error => logger.dError(s"Loading ReadonlyREST main settings from file failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST main settings from file:\n${settings.rawSettings.rawYaml.show}") - ) - .leftMap(error => StartingFailure(error.show)) - } yield loadedSettings - } - - private def loadTestSettingsFromIndex() = { - for { - _ <- lift(logger.info(s"Loading ReadonlyREST test settings from index: ${testSettingsIndexSource.settingsIndex.show} ...")) - loadedSettings <- EitherT(testSettingsIndexSource.load()) - .biSemiflatTap( - error => logger.dInfo(s"Loading ReadonlyREST test settings from index failed: ${error.show}"), - settings => logger.dDebug(s"Loaded ReadonlyREST test settings from index: ${settings.rawSettings.rawYaml.show}") - ) - .leftMap(error => StartingFailure(error.show)) - .map(Option(_)) - } yield loadedSettings - } - - private def lift[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) -} diff --git a/core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/MainRorSettings.scala similarity index 95% rename from core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/MainRorSettings.scala index dfed1b4972..17911989fc 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/MainRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/MainRorSettings.scala @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.ror final case class MainRorSettings(rawSettings: RawRorSettings) - diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettings.scala similarity index 96% rename from core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettings.scala index 24d15b048e..32bb338b81 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettings.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.ror import cats.Eq import io.circe.Json diff --git a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettingsYamlParser.scala similarity index 75% rename from core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettingsYamlParser.scala index be662e4844..7f91110ea4 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/RawRorSettingsYamlParser.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/RawRorSettingsYamlParser.scala @@ -14,15 +14,13 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.ror import better.files.File -import cats.Show import io.circe.{Json, ParsingFailure} import squants.information.Information -import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError -import tech.beshu.ror.configuration.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} -import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.utils.yaml.YamlParser class RawRorSettingsYamlParser(maxSize: Information) { @@ -59,11 +57,5 @@ object RawRorSettingsYamlParser { case object NoRorSection extends ParsingRorSettingsError case object MoreThanOneRorSection extends ParsingRorSettingsError final case class InvalidContent(throwable: Throwable) extends ParsingRorSettingsError - - implicit val show: Show[ParsingRorSettingsError] = Show.show { - case NoRorSection => "Cannot find any 'readonlyrest' section in settings" - case MoreThanOneRorSection => "Only one 'readonlyrest' section is required" - case InvalidContent(ex) => s"Settings content is malformed. Details: ${ex.getMessage.show}" - } } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/TestRorSettings.scala similarity index 92% rename from core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/TestRorSettings.scala index fa83b2059d..729ee0260a 100644 --- a/core/src/main/scala/tech/beshu/ror/configuration/TestRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/TestRorSettings.scala @@ -14,10 +14,10 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.configuration +package tech.beshu.ror.settings.ror import tech.beshu.ror.accesscontrol.blocks.mocks.AuthServicesMocks -import tech.beshu.ror.configuration.TestRorSettings.Expiration +import tech.beshu.ror.settings.ror.TestRorSettings.Expiration import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.{Clock, Instant} diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/ForceLoadRorSettingsFromFileLoader.scala similarity index 50% rename from core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/loader/ForceLoadRorSettingsFromFileLoader.scala index 2d6028b655..1ba99f0c5b 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/StartingRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/ForceLoadRorSettingsFromFileLoader.scala @@ -14,13 +14,23 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.loader +package tech.beshu.ror.settings.ror.loader import monix.eval.Task -import tech.beshu.ror.boot.ReadonlyRest.StartingFailure -import tech.beshu.ror.configuration.{MainRorSettings, TestRorSettings} +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.source.FileSettingsSource +import tech.beshu.ror.settings.ror.{MainRorSettings, TestRorSettings} -trait StartingRorSettingsLoader { +class ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource: FileSettingsSource[MainRorSettings]) + extends StartingRorSettingsLoader with Logging { - def load(): Task[Either[StartingFailure, (MainRorSettings, Option[TestRorSettings])]] -} + override def load(): Task[Either[LoadingError, (MainRorSettings, Option[TestRorSettings])]] = { + val result = loadSettingsFromSource( + source = mainSettingsFileSource, + settingsDescription = s"main settings from file '${mainSettingsFileSource.settingsFile.show}''" + ) + result.map((_, None)).value + } + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala similarity index 81% rename from core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index ba2371897a..59aa8e5556 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -14,14 +14,15 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.loader +package tech.beshu.ror.settings.ror.loader import cats.Show import cats.data.EitherT import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadFromIndexParameters +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings trait RetryStrategy { def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] @@ -34,25 +35,25 @@ object NoRetryStrategy extends RetryStrategy { operation } -class ConfigurableRetryStrategy(params: LoadFromIndexParameters) // todo: custom case class +class ConfigurableRetryStrategy(config: LoadingRetryStrategySettings) extends RetryStrategy with Logging { override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] = - attemptWithRetry(operation, currentAttempt = 1, params.loadingAttemptsCount.value.value) + attemptWithRetry(operation, currentAttempt = 1, config.attemptsCount.value.value) private def attemptWithRetry[ERROR : Show, A](operation: Task[Either[ERROR, A]], currentAttempt: Int, maxAttempts: Int): Task[Either[ERROR, A]] = { - val delay = if (currentAttempt == 1) params.loadingDelay.value.value else params.loadingAttemptsInterval.value.value + val delay = if (currentAttempt == 1) config.delay.value.value else config.attemptsInterval.value.value for { _ <- Task.sleep(delay) result <- operation finalResult <- result match { case Right(value) => Task.now(Right(value)) - // todo: better mesages + // todo: better messages case Left(error) if shouldRetry(currentAttempt, maxAttempts) => - logger.debug(s"Retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${params.loadingAttemptsInterval.show}...") + logger.debug(s"Retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${config.attemptsInterval.show}...") attemptWithRetry(operation, currentAttempt + 1, maxAttempts) case Left(error) => logger.debug(s"Operation failed after $currentAttempt attempts: ${error.show}") diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala new file mode 100644 index 0000000000..efe762b09a --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -0,0 +1,64 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.ror.loader + +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.source.* +import tech.beshu.ror.settings.ror.{MainRorSettings, TestRorSettings} + +class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIndexSource: MainSettingsIndexSource, + mainSettingsIndexLoadingRetryStrategy: RetryStrategy, + mainSettingsFileSource: MainSettingsFileSource, + testSettingsIndexSource: TestSettingsIndexSource) + extends StartingRorSettingsLoader with Logging { + + override def load(): Task[Either[LoadingError, (MainRorSettings, Option[TestRorSettings])]] = { + val result = for { + mainSettings <- mainSettingsIndexLoadingRetryStrategy + .withRetryT(loadMainSettingsFromIndex()) + .orElse(loadMainSettingsFromFile()) + testSettings <- loadTestSettingsFromIndex() + .map(Option.apply) + .recover { case _ => Option.empty[TestRorSettings] } + } yield (mainSettings, testSettings) + result.value + } + + private def loadMainSettingsFromIndex() = { + loadSettingsFromSource( + source = mainSettingsIndexSource, + settingsDescription = s"main settings from index '${mainSettingsIndexSource.settingsIndex.show}'" + ) + } + + private def loadMainSettingsFromFile() = { + loadSettingsFromSource( + source = mainSettingsFileSource, + settingsDescription = s"main settings from file '${mainSettingsFileSource.settingsFile.show}''" + ) + } + + private def loadTestSettingsFromIndex() = { + loadSettingsFromSource( + source = testSettingsIndexSource, + settingsDescription = s"test settings from index '${testSettingsIndexSource.settingsIndex.show}'" + ) + } + +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala new file mode 100644 index 0000000000..570ba9546c --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala @@ -0,0 +1,47 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.ror.loader + +import cats.Show +import cats.data.EitherT +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource +import tech.beshu.ror.settings.ror.{MainRorSettings, TestRorSettings} +import tech.beshu.ror.utils.ScalaOps.{EitherTOps, LoggerOps} + +trait StartingRorSettingsLoader { + this: Logging => + + def load(): Task[Either[LoadingError, (MainRorSettings, Option[TestRorSettings])]] + + protected def loadSettingsFromSource[S: Show, E: Show](source: ReadOnlySettingsSource[S, E], + settingsDescription: String): EitherT[Task, LoadingError, S] = { + for { + _ <- EitherT.liftTask(logger.info(s"Loading ReadonlyREST $settingsDescription ...")) + loadedSettings <- EitherT(source.load()) + .biSemiflatTap( + error => logger.dError(s"Loading ReadonlyREST $settingsDescription failed: ${error.show}"), + settings => logger.dDebug(s"Loaded ReadonlyREST $settingsDescription:\n${settings.show}") + ) + .leftMap(error => error.show) + } yield loadedSettings + } + + type LoadingError = String +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala similarity index 77% rename from core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala index be0ef89552..8ece7c6a76 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala @@ -14,17 +14,16 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source import better.files.File -import cats.Show import cats.data.EitherT import io.circe.{Decoder, Json} import monix.eval.Task -import tech.beshu.ror.settings.source.FileSettingsSource.FileSettingsLoadingError -import tech.beshu.ror.settings.source.FileSettingsSource.LoadingError.FileNotExist -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.FileSettingsSource.FileSettingsLoadingError +import tech.beshu.ror.settings.ror.source.FileSettingsSource.LoadingError.FileNotExist +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError class FileSettingsSource[SETTINGS: Decoder](val settingsFile: File) extends ReadOnlySettingsSource[SETTINGS, FileSettingsSource.LoadingError] { @@ -56,9 +55,5 @@ object FileSettingsSource { sealed trait LoadingError object LoadingError { final case class FileNotExist(file: File) extends LoadingError - - implicit val show: Show[LoadingError] = Show.show { - case FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" - } } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala similarity index 76% rename from core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala index 05e24c5a6a..4d0a8677df 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala @@ -14,20 +14,19 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source -import cats.Show import io.circe.syntax.* import io.circe.{Decoder, Encoder} import monix.eval.Task import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.es.IndexDocumentManager import tech.beshu.ror.es.IndexDocumentManager.CannotWriteToIndex -import tech.beshu.ror.settings.source.IndexSettingsSource.LoadingError.{DocumentNotFound, IndexNotFound} -import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.source.IndexSettingsSource.{IndexSettingsLoadingError, IndexSettingsSavingError, LoadingError, SavingError} -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.LoadingError.{DocumentNotFound, IndexNotFound} +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.{IndexSettingsLoadingError, IndexSettingsSavingError, LoadingError, SavingError} +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: IndexDocumentManager, val settingsIndex: IndexName.Full, @@ -72,11 +71,6 @@ object IndexSettingsSource { object LoadingError { case object IndexNotFound extends LoadingError case object DocumentNotFound extends LoadingError - - implicit val show: Show[LoadingError] = Show.show { - case IndexNotFound => "cannot find ReadonlyREST settings index" - case DocumentNotFound => "cannot found document with ReadonlyREST settings" - } } type IndexSettingsSavingError = SavingSettingsError[SavingError] @@ -84,9 +78,5 @@ object IndexSettingsSource { sealed trait SavingError object SavingError { case object CannotSaveSettings extends SavingError - - implicit val show: Show[SavingError] = Show.show { - case CannotSaveSettings => "Cannot save settings in the ReadonlyREST index" - } } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsFileSource.scala similarity index 91% rename from core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsFileSource.scala index 0e28e099f3..51fb0db664 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsFileSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsFileSource.scala @@ -14,11 +14,11 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source import io.circe.Decoder import tech.beshu.ror.accesscontrol.domain.RorSettingsFile -import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettingsYamlParser} class MainSettingsFileSource private (settingsFile: RorSettingsFile) (implicit decoder: Decoder[MainRorSettings]) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsIndexSource.scala similarity index 90% rename from core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsIndexSource.scala index 9c60a50ae6..e07cba0d7d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/MainSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/MainSettingsIndexSource.scala @@ -14,13 +14,13 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source import io.circe.Codec import tech.beshu.ror.accesscontrol.domain.RorSettingsIndex -import tech.beshu.ror.configuration.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.source.MainSettingsIndexSource.Const +import MainSettingsIndexSource.Const class MainSettingsIndexSource private(indexDocumentManager: IndexDocumentManager, settingsIndex: RorSettingsIndex) diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/RawRorSettingsCodec.scala similarity index 88% rename from core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/RawRorSettingsCodec.scala index f83574af2f..b8bdaaddba 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/RawRorSettingsCodec.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/RawRorSettingsCodec.scala @@ -14,12 +14,13 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source import cats.implicits.* import io.circe.Decoder.Result import io.circe.{Codec, Decoder, HCursor, Json} -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser} +import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.ror.{RawRorSettings, RawRorSettingsYamlParser} private [source] class RawRorSettingsCodec(yamlParser: RawRorSettingsYamlParser) extends Codec[RawRorSettings] { diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala similarity index 72% rename from core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala index ac4b55a28c..3d10408be1 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala @@ -14,13 +14,12 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source -import cats.Show import io.circe.{Decoder, Encoder} import monix.eval.Task -import tech.beshu.ror.settings.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError sealed trait SettingsSource[SETTINGS] @@ -33,11 +32,6 @@ object ReadOnlySettingsSource { final case class SettingsMalformed(cause: String) extends LoadingSettingsError[Nothing] final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError[ERROR] } - - implicit def show[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { - case LoadingSettingsError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" - case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) - } } trait ReadWriteSettingsSource[SETTINGS: Encoder : Decoder, READ_SPECIFIC_ERROR, WRITE_SPECIFIC_ERROR] @@ -50,8 +44,4 @@ object ReadWriteSettingsSource { object SavingSettingsError { final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError[ERROR] } - - implicit def show[ERROR: Show]: Show[SavingSettingsError[ERROR]] = Show.show { - case SavingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) - } } \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/TestSettingsIndexSource.scala similarity index 97% rename from core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala rename to core/src/main/scala/tech/beshu/ror/settings/ror/source/TestSettingsIndexSource.scala index 7f9c63d495..143e276b75 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/source/TestSettingsIndexSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/TestSettingsIndexSource.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.source +package tech.beshu.ror.settings.ror.source import eu.timepit.refined.types.string.NonEmptyString import io.circe.{Codec, Decoder, Encoder} @@ -27,10 +27,10 @@ import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.LdapServiceMock.L import tech.beshu.ror.accesscontrol.blocks.mocks.MocksProvider.{ExternalAuthenticationServiceMock, ExternalAuthorizationServiceMock, LdapServiceMock} import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{Group, GroupName, RorSettingsIndex, User} -import tech.beshu.ror.configuration.TestRorSettings.Expiration -import tech.beshu.ror.configuration.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} +import tech.beshu.ror.settings.ror.TestRorSettings.Expiration +import tech.beshu.ror.settings.ror.{RawRorSettings, RawRorSettingsYamlParser, TestRorSettings} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.source.TestSettingsIndexSource.Const +import TestSettingsIndexSource.Const import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.json.KeyCodec diff --git a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala index 3538710b7f..0b88e5f5ef 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala @@ -27,10 +27,10 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider import org.bouncycastle.openssl.PEMParser import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter -import tech.beshu.ror.configuration.SslConfiguration -import tech.beshu.ror.configuration.SslConfiguration.* -import tech.beshu.ror.configuration.SslConfiguration.ClientCertificateConfiguration.TruststoreBasedConfiguration -import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.KeystoreBasedConfiguration +import tech.beshu.ror.settings.es.SslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.* +import tech.beshu.ror.settings.es.SslConfiguration.ClientCertificateConfiguration.TruststoreBasedConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ServerCertificateConfiguration.KeystoreBasedConfiguration import tech.beshu.ror.implicits.* import java.io.{FileInputStream, FileReader, IOException} diff --git a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala index 1adcd5e5aa..f038a469a3 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/ScalaOps.scala @@ -261,4 +261,8 @@ object ScalaOps { Task.delay(logger.error(msg)) } } + + implicit class EitherTOps(t: EitherT.type) extends AnyVal { + def liftTask[A](value: => A): EitherT[Task, Nothing, A] = EitherT(Task.delay(Right(value))) + } } diff --git a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala index 00aa1dcef3..2b6f2589da 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/BaseYamlLoadedAccessControlTest.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.integration -import cats.implicits.* import monix.execution.Scheduler.Implicits.global import squants.information.Megabytes import tech.beshu.ror.SystemContext @@ -25,9 +24,10 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.{MocksProvider, NoOpMocksProvider} import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorSettingsBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorSettingsYamlParser +import tech.beshu.ror.implicits.* import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} import tech.beshu.ror.providers.* +import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.{BlockContextAssertion, defaultEsVersionForTests, unsafeNes} diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala index dfa7102c88..d9629eb990 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/AuditSettingsTests.scala @@ -34,9 +34,9 @@ import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreC import tech.beshu.ror.accesscontrol.factory.{Core, RawRorSettingsBasedCoreFactory, RorDependencies} import tech.beshu.ror.audit.adapters.DeprecatedAuditLogSerializerAdapter import tech.beshu.ror.audit.instances.{DefaultAuditLogSerializer, QueryAuditLogSerializer} -import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.EsVersion import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.utils.TestsUtils.* import java.time.{ZoneId, ZonedDateTime} diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala index e66e36040e..a9c3c3990d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/CoreFactoryTests.scala @@ -32,8 +32,8 @@ import tech.beshu.ror.accesscontrol.factory.HttpClientsFactory.HttpClient import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{BlocksLevelCreationError, RulesLevelCreationError} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, HttpClientsFactory, RawRorSettingsBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockHttpClientsFactoryWithFixedHttpClient, MockLdapConnectionPoolProvider} +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 67549a4f83..6c34859a02 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -30,8 +30,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.Rule import tech.beshu.ror.accesscontrol.blocks.{Block, ImpersonationWarning} import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.{CoreFactory, HttpClientsFactory, RawRorSettingsBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.MockHttpClientsFactory +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index c96bb6ee60..2981b30d7e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations.Unbo import tech.beshu.ror.accesscontrol.blocks.mocks.NoOpMocksProvider import tech.beshu.ror.accesscontrol.domain.{IndexName, LocalUsers, RorSettingsIndex, User} import tech.beshu.ror.accesscontrol.factory.{HttpClientsFactory, RawRorSettingsBasedCoreFactory} -import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.mocks.{MockHttpClientsFactory, MockLdapConnectionPoolProvider} +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.SingletonLdapContainers import tech.beshu.ror.utils.TestsUtils.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala similarity index 98% rename from core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala index e2bf308c9a..4320536632 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/RorIndexTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala @@ -36,9 +36,10 @@ import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsFil import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.boot.RorInstance.TestSettings import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} import tech.beshu.ror.es.{EsEnv, IndexDocumentManager} import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsUtils.* @@ -47,8 +48,7 @@ import java.util.UUID import scala.concurrent.duration.* import scala.language.postfixOps -// todo: change name -class RorIndexTest extends AnyWordSpec +class IndexSettingsRelatedRorCoreTest extends AnyWordSpec with Inside with OptionValues with EitherValues with MockFactory with Eventually { diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index a6ced5f907..157f117546 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -51,14 +51,15 @@ import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.configuration.EsConfigBasedRorSettings.LoadingError -import tech.beshu.ror.configuration.{EsConfigBasedRorSettings, RawRorSettings} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentManager} -import tech.beshu.ror.settings.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.RawRorSettings +import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala index 2fd6933118..aa985f1904 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala @@ -21,8 +21,8 @@ import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} -import tech.beshu.ror.configuration.{MalformedSettings, RorBootSettings} +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.{MalformedSettings, RorBootSettings} import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath} diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala index 2a37ed0194..12ac042741 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala @@ -22,9 +22,9 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile -import tech.beshu.ror.configuration.SslConfiguration.* -import tech.beshu.ror.configuration.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} -import tech.beshu.ror.configuration.{MalformedSettings, RorSslSettings} +import tech.beshu.ror.settings.es.SslConfiguration.* +import tech.beshu.ror.settings.es.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} +import tech.beshu.ror.settings.es.{MalformedSettings, RorSslSettings} import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.getResourcePath diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala index 3dd74a13b9..73189263da 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala @@ -23,7 +23,7 @@ import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.YamlFileBasedSettingsLoader +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader class YamlFileBasedRorSettingsLoaderTest extends AnyWordSpec with Inside { diff --git a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala index 33dfb4bd2d..af39700fca 100644 --- a/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala +++ b/core/src/test/scala/tech/beshu/ror/utils/TestsUtils.scala @@ -50,8 +50,8 @@ import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.Header.Name import tech.beshu.ror.accesscontrol.domain.KibanaApp.KibanaAppRegex import tech.beshu.ror.accesscontrol.domain.User.UserIdPattern -import tech.beshu.ror.configuration.RawRorSettings import tech.beshu.ror.es.EsVersion +import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.js.{JsCompiler, MozillaJsCompiler} import tech.beshu.ror.utils.json.JsonPath diff --git a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3f17635035..1d9463e0c0 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 0168bd0d19..d6a33e4d0e 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index c0257cc82c..042bd0cf4d 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 4cc4529252..4df2ed9fce 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 9a7946c917..0da3e50dd5 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 328935bbfb..41b53f471f 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index ecf83b066b..e391a67490 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -26,8 +26,8 @@ import org.elasticsearch.common.unit.TimeValue import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index def1155990..46540f37ef 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3f17635035..1d9463e0c0 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index fdb13305d4..3c2a69fa9f 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index c0257cc82c..042bd0cf4d 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 4cc4529252..4df2ed9fce 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 9a7946c917..0da3e50dd5 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 384b40bce9..58fdfcf958 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,8 +27,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index ecf83b066b..e391a67490 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -26,8 +26,8 @@ import org.elasticsearch.common.unit.TimeValue import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f3b70cb4ae..d3b8accded 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 6953fae982..7fd7129909 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index ce9ff9e1ce..7f12a91f4c 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 443de5791a..4720e2a6cf 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index a9f97756f7..3fb7bb8b1b 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 6953fae982..7fd7129909 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index ce9ff9e1ce..7f12a91f4c 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 443de5791a..4720e2a6cf 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index a9f97756f7..3fb7bb8b1b 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 6953fae982..7fd7129909 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index ce9ff9e1ce..7f12a91f4c 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 995c7e8bce..ac1ad056c8 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index a9f97756f7..3fb7bb8b1b 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 9857631e73..6d57ecd1bb 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -35,7 +35,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 3fd08cabab..e9c8206e4e 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.{SystemContext, constants} import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 07ee503ca8..321a6aa0b9 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 995c7e8bce..ac1ad056c8 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index a0a7d92ae4..2b457c7103 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index a2a3ecbc56..7f9aaa6d7c 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index e603e10ee6..1c077c28e5 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 07ee503ca8..321a6aa0b9 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 995c7e8bce..ac1ad056c8 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7344bc6c4f..3638642e19 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3f17635035..1d9463e0c0 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index fdb13305d4..3c2a69fa9f 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index c0257cc82c..042bd0cf4d 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 4cc4529252..4df2ed9fce 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 9a7946c917..0da3e50dd5 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 384b40bce9..58fdfcf958 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,8 +27,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index ecf83b066b..e391a67490 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -26,8 +26,8 @@ import org.elasticsearch.common.unit.TimeValue import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f3b70cb4ae..d3b8accded 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3f17635035..1d9463e0c0 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 7facfcdadd..8880aeb7ad 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index c0257cc82c..042bd0cf4d 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index d8999cdc37..f862d0257a 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 9a7946c917..0da3e50dd5 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index ce49f5aae2..60c2f10965 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -27,8 +27,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index ecf83b066b..e391a67490 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -26,8 +26,8 @@ import org.elasticsearch.common.unit.TimeValue import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f3b70cb4ae..d3b8accded 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3f17635035..1d9463e0c0 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index e8bee73bb0..8713187256 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index cdc9b97e4e..ef51710fdf 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 6b112f0e0e..c13bccc030 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -25,8 +25,8 @@ import org.elasticsearch.common.unit.TimeValue import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f3b70cb4ae..d3b8accded 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c50e3feada..09a360fac4 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 1077625840..c475f2581b 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 443de5791a..4720e2a6cf 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 1304142499..48c7e34c54 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3ee12048dc..88f2e8b4dc 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4636c90dd5..ab97b98f04 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 443de5791a..4720e2a6cf 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 1304142499..48c7e34c54 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3ac42afd15..385e17147e 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 6953fae982..7fd7129909 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 534ae8efea..c13d97c89e 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 5abe81e5d6..caeafd8a99 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 39a24eff61..25c8d6113b 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.action.support.nodes.BaseNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97cbeefff6..708e6d6176 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.env.Environment import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 443de5791a..4720e2a6cf 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5b78aca31a..8f44e4149c 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index a9f97756f7..3fb7bb8b1b 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cd73e6310c..18bb5fb961 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index a2a3ecbc56..7f9aaa6d7c 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 3564d323ba..0bc56705a1 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 8236536367..34aad32d86 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 995c7e8bce..ac1ad056c8 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 946cfa4c28..f69eef25d2 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 43c6fe0d6a..dedd7a8e7f 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -52,7 +52,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 0e55006e52..d6f4699d23 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 56afacb5bb..7438934b6f 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8ff275872a..7d6daf852f 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -53,7 +53,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 35dc2b9fea..c30df9b180 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..b1b9f30bd0 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 5eb518cb34..fe29ab8d0b 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -45,7 +45,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 4632c6ded2..35e57bce86 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..b1b9f30bd0 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 0077fa9ffc..6abefacddf 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -46,7 +46,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 4632c6ded2..35e57bce86 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..b1b9f30bd0 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 0077fa9ffc..6abefacddf 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -46,7 +46,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 4632c6ded2..35e57bce86 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..b1b9f30bd0 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 3d73191141..3e77841f84 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 4cb1a900b3..6c83268805 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index cb309e058b..4552b6e325 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -40,7 +40,7 @@ import java.util.concurrent.Executor import scala.annotation.unused import scala.concurrent.duration.* import scala.language.postfixOps -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest import tech.beshu.ror.es.utils.EsEnvProvider class TransportRRConfigAction(actionName: String, diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a304c06284..7ac7d78766 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -27,7 +27,7 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..b1b9f30bd0 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c688fa1c21..97ddd29ea6 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index a136d6f0e7..8b4591c523 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 21317a9d83..9e8b4485a2 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 8e74908a8a..6a9c7e16d3 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 3d44057e51..31a5826de5 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 59203f11f5..2892f898f9 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -23,7 +23,7 @@ import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 1f00261ee4..0ff995d0f2 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index a136d6f0e7..8b4591c523 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -47,7 +47,7 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 21317a9d83..9e8b4485a2 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 8e74908a8a..6a9c7e16d3 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -20,8 +20,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 3d44057e51..31a5826de5 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index 59203f11f5..2892f898f9 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -23,7 +23,7 @@ import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 1f00261ee4..0ff995d0f2 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 2b2ec4ab23..8325181e82 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8b2f8f7cb0..3a2c47fdca 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97ac49aa6f..53a610f3dd 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 946cfa4c28..f69eef25d2 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 2b2ec4ab23..8325181e82 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8b2f8f7cb0..3a2c47fdca 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97ac49aa6f..53a610f3dd 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 946cfa4c28..f69eef25d2 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 2b2ec4ab23..8325181e82 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 704e92a3f5..03dfcd748c 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97ac49aa6f..53a610f3dd 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index d0bd030271..7d5bdddcf7 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 8ccc1290f3..9d0b2a1a48 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 2b2ec4ab23..8325181e82 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 7b697970d2..9cf091a2db 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -50,7 +50,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 97ac49aa6f..53a610f3dd 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -30,8 +30,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.configuration.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 5631d98c22..aa076ad5a2 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 30c0db763d..f8d0659ab4 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1341967a56..9a279e99eb 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 5631d98c22..aa076ad5a2 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index f9f71f30b1..84a0ca989a 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 2537b67619..e87b222792 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1341967a56..9a279e99eb 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d3c8c290b0..300fa59dd9 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index ba64286bb4..bace72fc19 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 06382c443e..9f68d2d239 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1341967a56..9a279e99eb 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 4a3437a056..fcc712761c 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index ba64286bb4..bace72fc19 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index b36272726c..d6f842146b 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 06382c443e..9f68d2d239 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -51,7 +51,7 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.ReadonlyRestEsConfig import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java index 332bb90e1f..4c54fc5429 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; import java.io.IOException; diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java index 75d052eb16..91db914374 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java @@ -19,8 +19,8 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java index 39e7416033..3e49f6908a 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java @@ -21,8 +21,8 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; +import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; +import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; import java.io.IOException; import java.util.Arrays; diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala index 1341967a56..9a279e99eb 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala @@ -29,8 +29,8 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.TransportService import tech.beshu.ror.SystemContext -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} +import tech.beshu.ror.settings.es.loader.* +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} import tech.beshu.ror.es.IndexJsonContentService import tech.beshu.ror.es.services.EsIndexJsonContentService import tech.beshu.ror.es.utils.EsEnvProvider diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala index a81dc7ccdb..3530227ea7 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala @@ -28,8 +28,8 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.GET import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.configuration.loader.distributed.{NodeConfigRequest, Timeout} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId +import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} import scala.jdk.CollectionConverters.* diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala index 5f1ba63898..9bd3910dcf 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala @@ -23,8 +23,8 @@ import org.elasticsearch.xcontent.XContentBuilder import org.elasticsearch.rest.action.RestBuilderListener import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse +import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} import scala.jdk.CollectionConverters.* diff --git a/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..ad66bd8f35 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootConfiguration +import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 56afacb5bb..7438934b6f 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..3728ca317d 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 3e64256cb3..44543b95cf 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -35,7 +35,7 @@ import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator import tech.beshu.ror.boot.* import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 369e81dc3c..2269208f85 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -48,8 +48,8 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.EsConfigBasedRorSettings -import tech.beshu.ror.configuration.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction diff --git a/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index 95b82d2e22..9c00906853 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,8 +16,8 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootSettings -import tech.beshu.ror.configuration.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 5dd4a49759..0e58945176 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslSettings +import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cad324634e..a62e3fa009 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslSettings +import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort From 2bba1df3c6bf6bf25d38cd6819f19fb5a3131d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 1 Oct 2025 17:32:29 +0200 Subject: [PATCH 036/103] refactoring --- .../accesscontrol/factory/CoreFactory.scala | 12 +- .../factory/GlobalSettings.scala | 2 +- .../GlobalStaticSettingsDecoder.scala | 4 +- .../factory/decoders/ruleDecoders.scala | 4 +- .../kibana/KibanaUserDataRuleDecoder.scala | 4 +- .../tech/beshu/ror/api/AuthMockApi.scala | 6 +- .../SecurityProviderConfiguratorForFips.scala | 2 +- .../ror/settings/es/RorSslSettings.scala | 138 ++++++++--------- .../tech/beshu/ror/utils/SSLCertHelper.scala | 142 +++++++++--------- .../acl/EnabledAccessControlListTests.scala | 2 +- .../user/UserDefinitionsValidatorTests.scala | 2 +- .../definitions/GlobalSettingsTests.scala | 124 +++++++-------- .../ImpersonationSettingsTests.scala | 2 +- .../rules/auth/UsersRuleSettingsTests.scala | 2 +- ...rationTest.scala => SslSettingsTest.scala} | 22 +-- .../es/ssl/SSLNetty4HttpServerTransport.scala | 2 +- .../SSLNetty4InternodeServerTransport.scala | 2 +- 17 files changed, 238 insertions(+), 234 deletions(-) rename core/src/test/scala/tech/beshu/ror/unit/configuration/{SslConfigurationTest.scala => SslSettingsTest.scala} (79%) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala index 7f7342c545..8c31fe3a79 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/CoreFactory.scala @@ -98,17 +98,17 @@ class RawRorSettingsBasedCoreFactory(esEnv: EsEnv) } private def createCoreFromRorSection(rorSection: Json, - rorIndexNameConfiguration: RorSettingsIndex, + rorSettingsIndex: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { - val jsonConfigResolver = new JsonStaticVariablesResolver( + val resolver = new JsonStaticVariablesResolver( systemContext.envVarsProvider, TransformationCompiler.withoutAliases(systemContext.variablesFunctions), ) - jsonConfigResolver.resolve(rorSection) match { + resolver.resolve(rorSection) match { case Right(resolvedRorSection) => - createFrom(resolvedRorSection, rorIndexNameConfiguration, httpClientFactory, ldapConnectionPoolProvider, mocksProvider).map { + createFrom(resolvedRorSection, rorSettingsIndex, httpClientFactory, ldapConnectionPoolProvider, mocksProvider).map { case Right(settings) => Right(settings) case Left(failure) => @@ -120,7 +120,7 @@ class RawRorSettingsBasedCoreFactory(esEnv: EsEnv) } private def createFrom(settingsJson: Json, - rorConfigurationIndex: RorSettingsIndex, + settingsIndex: RorSettingsIndex, httpClientFactory: HttpClientsFactory, ldapConnectionPoolProvider: UnboundidLdapConnectionPoolProvider, mocksProvider: MocksProvider) = { @@ -131,7 +131,7 @@ class RawRorSettingsBasedCoreFactory(esEnv: EsEnv) AsyncDecoderCreator.from(Decoder.const(Core(DisabledAccessControlList, RorDependencies.noOp, None))) } else { for { - globalSettings <- AsyncDecoderCreator.from(GlobalStaticSettingsDecoder.instance(rorConfigurationIndex)) + globalSettings <- AsyncDecoderCreator.from(GlobalStaticSettingsDecoder.instance(settingsIndex)) core <- coreDecoder(httpClientFactory, ldapConnectionPoolProvider, globalSettings, mocksProvider) } yield core } diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala index de89ed7c7b..493e6d801d 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/GlobalSettings.scala @@ -21,7 +21,7 @@ import tech.beshu.ror.accesscontrol.domain.{CaseSensitivity, RorSettingsIndex} final case class GlobalSettings(showBasicAuthPrompt: Boolean, forbiddenRequestMessage: String, flsEngine: GlobalSettings.FlsEngine, - configurationIndex: RorSettingsIndex, + settingsIndex: RorSettingsIndex, userIdCaseSensitivity: CaseSensitivity, usersDefinitionDuplicateUsernamesValidationEnabled: Boolean) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala index 9b0075c52c..6b1a708fa7 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/GlobalStaticSettingsDecoder.scala @@ -29,7 +29,7 @@ object GlobalStaticSettingsDecoder { private val globalSettingsSectionName = "global_settings" - def instance(rorConfigurationIndex: RorSettingsIndex): Decoder[GlobalSettings] = { + def instance(settingsIndex: RorSettingsIndex): Decoder[GlobalSettings] = { for { showBasicAuthPrompt <- decoderFor[Boolean]("prompt_for_basic_auth") forbiddenRequestMessage <- decoderFor[String]("response_if_req_forbidden") @@ -40,7 +40,7 @@ object GlobalStaticSettingsDecoder { showBasicAuthPrompt.getOrElse(false), forbiddenRequestMessage.getOrElse(GlobalSettings.defaultForbiddenRequestMessage), flsEngine.getOrElse(GlobalSettings.FlsEngine.ESWithLucene), - rorConfigurationIndex, + settingsIndex, userIdCaseSensitivity.getOrElse(CaseSensitivity.Enabled), usersDefinitionDuplicateUsernamesValidationEnabled.getOrElse(true) ) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala index a799e777fb..1a27abf77b 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/ruleDecoders.scala @@ -88,8 +88,8 @@ object ruleDecoders { case HeadersOrRule.Name.name => Some(HeadersOrRuleDecoder) case HostsRule.Name.name => Some(new HostsRuleDecoder(variableCreator)) case IndicesRule.Name.name => Some(new IndicesRuleDecoders(variableCreator, systemContext.uniqueIdentifierGenerator)) - case KibanaUserDataRule.Name.name => Some(new KibanaUserDataRuleDecoder(globalSettings.configurationIndex, variableCreator)(systemContext.jsCompiler)) - case KibanaAccessRule.Name.name => Some(new KibanaAccessRuleDecoder(globalSettings.configurationIndex)) + case KibanaUserDataRule.Name.name => Some(new KibanaUserDataRuleDecoder(globalSettings.settingsIndex, variableCreator)(systemContext.jsCompiler)) + case KibanaAccessRule.Name.name => Some(new KibanaAccessRuleDecoder(globalSettings.settingsIndex)) case KibanaHideAppsRule.Name.name => Some(new KibanaHideAppsRuleDecoder()(systemContext.jsCompiler)) case KibanaIndexRule.Name.name => Some(new KibanaIndexRuleDecoder(variableCreator)) case KibanaTemplateIndexRule.Name.name => Some(new KibanaTemplateIndexRuleDecoder(variableCreator)) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala index 510731b2b2..f0e0ed79e0 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaUserDataRuleDecoder.scala @@ -39,7 +39,7 @@ import tech.beshu.ror.utils.js.JsCompiler import scala.util.{Failure, Success} -class KibanaUserDataRuleDecoder(configurationIndex: RorSettingsIndex, +class KibanaUserDataRuleDecoder(settingsIndex: RorSettingsIndex, variableCreator: RuntimeResolvableVariableCreator) (implicit jsCompiler: JsCompiler) extends RuleBaseDecoderWithoutAssociatedFields[KibanaUserDataRule] @@ -69,7 +69,7 @@ class KibanaUserDataRuleDecoder(configurationIndex: RorSettingsIndex, appsToHide = appsToHide.getOrElse(Set.empty), allowedApiPaths = allowedApiPaths.getOrElse(Set.empty), metadata = metadataResolvableJsonRepresentation, - rorIndex = configurationIndex + rorIndex = settingsIndex )) } .map(RuleDefinition.create[KibanaUserDataRule](_)) diff --git a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala index 5a95554583..56f49b2183 100644 --- a/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/AuthMockApi.scala @@ -58,7 +58,7 @@ class AuthMockApi(rorInstance: RorInstance) private def provideAuthMock() (implicit requestId: RequestId): Task[AuthMockResponse] = { - withRorConfigAuthServices( + withRorSettingsAuthServices( action = readCurrentAuthMocks, onNotSet = AuthMockResponse.ProvideAuthMock.NotConfigured.apply, onInvalidated = AuthMockResponse.ProvideAuthMock.Invalidated.apply @@ -101,14 +101,14 @@ class AuthMockApi(rorInstance: RorInstance) private def readCurrentAuthServices() (implicit requestId: RequestId): EitherT[Task, AuthMockResponse, RorDependencies.Services] = { - EitherT(withRorConfigAuthServices( + EitherT(withRorSettingsAuthServices( action = identity, onNotSet = AuthMockResponse.UpdateAuthMock.NotConfigured.apply, onInvalidated = AuthMockResponse.UpdateAuthMock.Invalidated.apply )) } - private def withRorConfigAuthServices[A, B](action: RorDependencies.Services => B, + private def withRorSettingsAuthServices[A, B](action: RorDependencies.Services => B, onNotSet: String => A, onInvalidated: String => A) (implicit requestId: RequestId): Task[Either[A, B]] = { diff --git a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala index f0c657999c..97cc92bf0b 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SecurityProviderConfiguratorForFips.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.boot import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider import tech.beshu.ror.settings.es.RorSslSettings -import tech.beshu.ror.settings.es.SslConfiguration.FipsMode.{NonFips, SslOnly} +import tech.beshu.ror.settings.es.SslSettings.FipsMode.{NonFips, SslOnly} import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import java.security.Security diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index 288dfa8c87..991c5e9da0 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -24,7 +24,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.es.SslConfiguration.* +import tech.beshu.ror.settings.es.SslSettings.* import tech.beshu.ror.utils.SSLCertHelper sealed trait RorSslSettings @@ -93,14 +93,14 @@ object RorSslSettings extends Logging { } } -sealed trait SslConfiguration { - def serverCertificateConfiguration: SslConfiguration.ServerCertificateConfiguration +sealed trait SslSettings { + def serverCertificateSettings: SslSettings.ServerCertificateSettings - def clientCertificateConfiguration: Option[SslConfiguration.ClientCertificateConfiguration] + def clientCertificateSettings: Option[SslSettings.ClientCertificateSettings] - def allowedProtocols: Set[SslConfiguration.Protocol] + def allowedProtocols: Set[SslSettings.Protocol] - def allowedCiphers: Set[SslConfiguration.Cipher] + def allowedCiphers: Set[SslSettings.Cipher] def clientAuthenticationEnabled: Boolean @@ -109,7 +109,7 @@ sealed trait SslConfiguration { def fipsMode: FipsMode } -object SslConfiguration { +object SslSettings { final case class KeystorePassword(value: String) final case class KeystoreFile(value: File) @@ -123,43 +123,47 @@ object SslConfiguration { final case class Cipher(value: String) final case class Protocol(value: String) - sealed trait ServerCertificateConfiguration - object ServerCertificateConfiguration { - final case class KeystoreBasedConfiguration(keystoreFile: KeystoreFile, - keystorePassword: Option[KeystorePassword], - keyAlias: Option[KeyAlias], - keyPass: Option[KeyPass]) extends ServerCertificateConfiguration - final case class FileBasedConfiguration(serverCertificateKeyFile: ServerCertificateKeyFile, - serverCertificateFile: ServerCertificateFile) extends ServerCertificateConfiguration + sealed trait ServerCertificateSettings + object ServerCertificateSettings { + final case class KeystoreBasedSettings(keystoreFile: KeystoreFile, + keystorePassword: Option[KeystorePassword], + keyAlias: Option[KeyAlias], + keyPass: Option[KeyPass]) + extends ServerCertificateSettings + final case class FileBasedSettings(serverCertificateKeyFile: ServerCertificateKeyFile, + serverCertificateFile: ServerCertificateFile) + extends ServerCertificateSettings } - sealed trait ClientCertificateConfiguration - object ClientCertificateConfiguration { - final case class TruststoreBasedConfiguration(truststoreFile: TruststoreFile, - truststorePassword: Option[TruststorePassword]) extends ClientCertificateConfiguration - final case class FileBasedConfiguration(clientTrustedCertificateFile: ClientTrustedCertificateFile) extends ClientCertificateConfiguration + sealed trait ClientCertificateSettings + object ClientCertificateSettings { + final case class TruststoreBasedSettings(truststoreFile: TruststoreFile, + truststorePassword: Option[TruststorePassword]) + extends ClientCertificateSettings + final case class FileBasedSettings(clientTrustedCertificateFile: ClientTrustedCertificateFile) + extends ClientCertificateSettings } - final case class ExternalSslSettings(serverCertificateConfiguration: ServerCertificateConfiguration, - clientCertificateConfiguration: Option[ClientCertificateConfiguration], - allowedProtocols: Set[SslConfiguration.Protocol], - allowedCiphers: Set[SslConfiguration.Cipher], + final case class ExternalSslSettings(serverCertificateSettings: ServerCertificateSettings, + clientCertificateSettings: Option[ClientCertificateSettings], + allowedProtocols: Set[SslSettings.Protocol], + allowedCiphers: Set[SslSettings.Cipher], clientAuthenticationEnabled: Boolean, fipsMode: FipsMode) - extends SslConfiguration { + extends SslSettings { val certificateVerificationEnabled: Boolean = false } - final case class InternodeSslSettings(serverCertificateConfiguration: ServerCertificateConfiguration, - clientCertificateConfiguration: Option[ClientCertificateConfiguration], - allowedProtocols: Set[SslConfiguration.Protocol], - allowedCiphers: Set[SslConfiguration.Cipher], + final case class InternodeSslSettings(serverCertificateSettings: ServerCertificateSettings, + clientCertificateSettings: Option[ClientCertificateSettings], + allowedProtocols: Set[SslSettings.Protocol], + allowedCiphers: Set[SslSettings.Cipher], clientAuthenticationEnabled: Boolean, certificateVerificationEnabled: Boolean, hostnameVerificationEnabled: Boolean, fipsMode: FipsMode) - extends SslConfiguration + extends SslSettings sealed trait FipsMode object FipsMode { @@ -194,10 +198,10 @@ private object SslDecoders extends Logging { val clientTrustedCertificateFile = "client_trusted_certificate_file" } - final case class CommonSslProperties(serverCertificateConfiguration: ServerCertificateConfiguration, - clientCertificateConfiguration: Option[ClientCertificateConfiguration], - allowedProtocols: Set[SslConfiguration.Protocol], - allowedCiphers: Set[SslConfiguration.Cipher], + final case class CommonSslProperties(serverCertificateSettings: ServerCertificateSettings, + clientCertificateSettings: Option[ClientCertificateSettings], + allowedProtocols: Set[SslSettings.Protocol], + allowedCiphers: Set[SslSettings.Cipher], clientAuthentication: Option[Boolean]) private implicit val keystorePasswordDecoder: Decoder[KeystorePassword] = DecoderHelpers.decodeStringLike.map(KeystorePassword.apply) @@ -207,29 +211,29 @@ private object SslDecoders extends Logging { private implicit val cipherDecoder: Decoder[Cipher] = DecoderHelpers.decodeStringLike.map(Cipher.apply) private implicit val protocolDecoder: Decoder[Protocol] = DecoderHelpers.decodeStringLike.map(Protocol.apply) - private def clientCertificateConfigurationDecoder(basePath: File): Decoder[Option[ClientCertificateConfiguration]] = { + private def clientCertificateSettingsDecoder(basePath: File): Decoder[Option[ClientCertificateSettings]] = { val aFileDecoder: Decoder[File] = fileDecoder(basePath) implicit val truststoreFileDecoder = aFileDecoder.map(TruststoreFile.apply) implicit val clientTrustedCertificateFileDecoder = aFileDecoder.map(ClientTrustedCertificateFile.apply) - val truststoreBasedClientCertificateConfigurationDecoder: Decoder[ClientCertificateConfiguration] = - Decoder.forProduct2(consts.truststoreFile, consts.truststorePass)(ClientCertificateConfiguration.TruststoreBasedConfiguration.apply) - val fileBasedClientCertificateConfigurationDecoder: Decoder[ClientCertificateConfiguration] = - Decoder.forProduct1(consts.clientTrustedCertificateFile)(ClientCertificateConfiguration.FileBasedConfiguration.apply) + val truststoreBasedClientCertificateSettingsDecoder: Decoder[ClientCertificateSettings] = + Decoder.forProduct2(consts.truststoreFile, consts.truststorePass)(ClientCertificateSettings.TruststoreBasedSettings.apply) + val fileBasedClientCertificateSettingsDecoder: Decoder[ClientCertificateSettings] = + Decoder.forProduct1(consts.clientTrustedCertificateFile)(ClientCertificateSettings.FileBasedSettings.apply) Decoder.instance { c => val truststoreBasedKeys = Set(consts.truststoreFile, consts.truststorePass) val fileBasedKeys = Set(consts.clientTrustedCertificateFile) val presentKeys = c.keys.fold[Set[String]](Set.empty)(_.toSet) if (presentKeys.intersect(truststoreBasedKeys).nonEmpty && presentKeys.intersect(fileBasedKeys).nonEmpty) { - val errorMessage = s"Field sets [${fileBasedKeys.show}] and [${truststoreBasedKeys.show}] could not be present in the same configuration section" + val errorMessage = s"Field sets [${fileBasedKeys.show}] and [${truststoreBasedKeys.show}] could not be present in the same settings section" logger.error(errorMessage) Left(DecodingFailure(errorMessage, List.empty)) } else if (presentKeys.intersect(truststoreBasedKeys).nonEmpty) { - truststoreBasedClientCertificateConfigurationDecoder(c) + truststoreBasedClientCertificateSettingsDecoder(c) .map(Option.apply) } else if (presentKeys.intersect(fileBasedKeys).nonEmpty) { if (SSLCertHelper.isPEMHandlingAvailable) { - fileBasedClientCertificateConfigurationDecoder(c) + fileBasedClientCertificateSettingsDecoder(c) .map(Option.apply) } else { val errorMessage = "PEM File Handling is not available in your current deployment of Elasticsearch" @@ -242,35 +246,35 @@ private object SslDecoders extends Logging { } } - private def serverCertificateConfigurationDecoder(basePath: File): Decoder[ServerCertificateConfiguration] = { + private def serverCertificateSettingsDecoder(basePath: File): Decoder[ServerCertificateSettings] = { val aFileDecoder: Decoder[File] = fileDecoder(basePath) implicit val keystoreFileDecoder = aFileDecoder.map(KeystoreFile.apply) implicit val serverCertificateFileDecoder = aFileDecoder.map(ServerCertificateFile.apply) implicit val serverCertificateKeyFileDecoder = aFileDecoder.map(ServerCertificateKeyFile.apply) - val keystoreBasedServerCertificateConfigurationDecoder: Decoder[ServerCertificateConfiguration] = - Decoder.forProduct4(consts.keystoreFile, consts.keystorePass, consts.keyAlias, consts.keyPass)(ServerCertificateConfiguration.KeystoreBasedConfiguration.apply) - val fileBasedServerCertificateConfigurationDecoder: Decoder[ServerCertificateConfiguration] = - Decoder.forProduct2(consts.serverCertificateKeyFile, consts.serverCertificateFile)(ServerCertificateConfiguration.FileBasedConfiguration.apply) + val keystoreBasedServerCertificateSettingsDecoder: Decoder[ServerCertificateSettings] = + Decoder.forProduct4(consts.keystoreFile, consts.keystorePass, consts.keyAlias, consts.keyPass)(ServerCertificateSettings.KeystoreBasedSettings.apply) + val fileBasedServerCertificateSettingsDecoder: Decoder[ServerCertificateSettings] = + Decoder.forProduct2(consts.serverCertificateKeyFile, consts.serverCertificateFile)(ServerCertificateSettings.FileBasedSettings.apply) Decoder.instance { c => val keystoreBasedKeys = Set(consts.keystoreFile, consts.keystorePass, consts.keyPass, consts.keyAlias) val fileBasedKeys = Set(consts.serverCertificateKeyFile, consts.serverCertificateFile) val presentKeys = c.keys.fold[Set[String]](Set.empty)(_.toSet) if (presentKeys.intersect(keystoreBasedKeys).nonEmpty && presentKeys.intersect(fileBasedKeys).nonEmpty) { - val errorMessage = s"Field sets [${fileBasedKeys.show}] and [${keystoreBasedKeys.show}] could not be present in the same configuration section" + val errorMessage = s"Field sets [${fileBasedKeys.show}] and [${keystoreBasedKeys.show}] could not be present in the same settings section" logger.error(errorMessage) Left(DecodingFailure(errorMessage, List.empty)) } else if (presentKeys.intersect(keystoreBasedKeys).nonEmpty) { - keystoreBasedServerCertificateConfigurationDecoder(c) + keystoreBasedServerCertificateSettingsDecoder(c) } else if (presentKeys.intersect(fileBasedKeys).nonEmpty) { if (SSLCertHelper.isPEMHandlingAvailable) { - fileBasedServerCertificateConfigurationDecoder(c) + fileBasedServerCertificateSettingsDecoder(c) } else { val errorMessage = "PEM File Handling is not available in your current deployment of Elasticsearch" logger.error(errorMessage) Left(DecodingFailure(errorMessage, List.empty)) } } else { - val errorMessage = "There was no SSL configuration present for server" + val errorMessage = "There was no SSL settings present for server" logger.error(errorMessage) Left(DecodingFailure(errorMessage, List.empty)) } @@ -281,18 +285,18 @@ private object SslDecoders extends Logging { implicit val isFipsCompliantDecoder: Decoder[FipsMode] = Decoder.decodeString.emap { case "NON_FIPS" => Right(FipsMode.NonFips) case "SSL_ONLY" => Right(FipsMode.SslOnly) - case _ => Left("Invalid configuration option for FIPS MODE. Valid values are: NON_FIPS, SSL_ONLY") + case _ => Left("Invalid settings option for FIPS MODE. Valid values are: NON_FIPS, SSL_ONLY") } for { fipsMode <- c.downField(consts.rorSection).downField(consts.fipsMode).as[Option[FipsMode]] interNodeSsl <- { - implicit val internodeSslConfigDecoder: Decoder[Option[InternodeSslSettings]] = - sslInternodeConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + implicit val internodeSslSettingsDecoder: Decoder[Option[InternodeSslSettings]] = + sslInternodeSettingsDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) c.downField(consts.rorSection).downField(consts.internodeSsl).as[Option[Option[InternodeSslSettings]]] } externalSsl <- { - implicit val externalSslConfigDecoder: Decoder[Option[ExternalSslSettings]] = - sslExternalConfigurationDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) + implicit val externalSslSettingsDecoder: Decoder[Option[ExternalSslSettings]] = + sslExternalSettingsDecoder(basePath, fipsMode.getOrElse(FipsMode.NonFips)) c.downField(consts.rorSection).downField(consts.externalSsl).as[Option[Option[ExternalSslSettings]]] } } yield { @@ -305,7 +309,7 @@ private object SslDecoders extends Logging { } } - private def sslInternodeConfigurationDecoder(basePath: File, + private def sslInternodeSettingsDecoder(basePath: File, fipsMode: FipsMode): Decoder[Option[InternodeSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { @@ -315,8 +319,8 @@ private object SslDecoders extends Logging { sslCommonProperties <- sslCommonPropertiesDecoder(basePath, c) } yield InternodeSslSettings( - serverCertificateConfiguration = sslCommonProperties.serverCertificateConfiguration, - clientCertificateConfiguration = sslCommonProperties.clientCertificateConfiguration, + serverCertificateSettings = sslCommonProperties.serverCertificateSettings, + clientCertificateSettings = sslCommonProperties.clientCertificateSettings, allowedProtocols = sslCommonProperties.allowedProtocols, allowedCiphers = sslCommonProperties.allowedCiphers, clientAuthenticationEnabled = sslCommonProperties.clientAuthentication.getOrElse(false), @@ -327,7 +331,7 @@ private object SslDecoders extends Logging { } } - private def sslExternalConfigurationDecoder(basePath: File, + private def sslExternalSettingsDecoder(basePath: File, fipsMode: FipsMode): Decoder[Option[ExternalSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { @@ -335,8 +339,8 @@ private object SslDecoders extends Logging { sslCommonProperties <- sslCommonPropertiesDecoder(basePath, c) } yield ExternalSslSettings( - serverCertificateConfiguration = sslCommonProperties.serverCertificateConfiguration, - clientCertificateConfiguration = sslCommonProperties.clientCertificateConfiguration, + serverCertificateSettings = sslCommonProperties.serverCertificateSettings, + clientCertificateSettings = sslCommonProperties.clientCertificateSettings, allowedProtocols = sslCommonProperties.allowedProtocols, allowedCiphers = sslCommonProperties.allowedCiphers, clientAuthenticationEnabled = sslCommonProperties.clientAuthentication.orElse(verification).getOrElse(false), @@ -350,19 +354,19 @@ private object SslDecoders extends Logging { ciphers <- c.downField(consts.allowedCiphers).as[Option[Set[Cipher]]] protocols <- c.downField(consts.allowedProtocols).as[Option[Set[Protocol]]] clientAuthentication <- c.downField(consts.clientAuthentication).as[Option[Boolean]] - serverCertificateConfiguration <- serverCertificateConfigurationDecoder(basePath).apply(c) - clientCertificateConfiguration <- clientCertificateConfigurationDecoder(basePath).apply(c) + serverCertificateSettings <- serverCertificateSettingsDecoder(basePath).apply(c) + clientCertificateSettings <- clientCertificateSettingsDecoder(basePath).apply(c) } yield CommonSslProperties( - serverCertificateConfiguration = serverCertificateConfiguration, - clientCertificateConfiguration = clientCertificateConfiguration, + serverCertificateSettings = serverCertificateSettings, + clientCertificateSettings = clientCertificateSettings, allowedProtocols = protocols.getOrElse(Set.empty[Protocol]), allowedCiphers = ciphers.getOrElse(Set.empty[Cipher]), clientAuthentication = clientAuthentication, ) } - private def whenEnabled[T <: SslConfiguration](cursor: HCursor)(decoding: => Either[DecodingFailure, T]) = { + private def whenEnabled[T <: SslSettings](cursor: HCursor)(decoding: => Either[DecodingFailure, T]) = { for { isEnabled <- cursor.downField(consts.enable).as[Option[Boolean]] result <- if (isEnabled.getOrElse(true)) decoding.map(Some.apply) else Right(None) diff --git a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala index 0b88e5f5ef..99b22268fe 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala @@ -27,10 +27,10 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider import org.bouncycastle.openssl.PEMParser import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter -import tech.beshu.ror.settings.es.SslConfiguration -import tech.beshu.ror.settings.es.SslConfiguration.* -import tech.beshu.ror.settings.es.SslConfiguration.ClientCertificateConfiguration.TruststoreBasedConfiguration -import tech.beshu.ror.settings.es.SslConfiguration.ServerCertificateConfiguration.KeystoreBasedConfiguration +import tech.beshu.ror.settings.es.SslSettings +import tech.beshu.ror.settings.es.SslSettings.* +import tech.beshu.ror.settings.es.SslSettings.ClientCertificateSettings.TruststoreBasedSettings +import tech.beshu.ror.settings.es.SslSettings.ServerCertificateSettings.KeystoreBasedSettings import tech.beshu.ror.implicits.* import java.io.{FileInputStream, FileReader, IOException} @@ -65,16 +65,16 @@ object SSLCertHelper extends Logging { sslEngine } - def prepareClientSSLContext(sslConfiguration: SslConfiguration, + def prepareClientSSLContext(sslSettings: SslSettings, fipsCompliant: Boolean, certificateVerificationEnabled: Boolean): SslContext = { val builder = if (certificateVerificationEnabled) { - sslConfiguration.clientCertificateConfiguration match { - case Some(truststoreBasedConfiguration: TruststoreBasedConfiguration) => - SslContextBuilder.forClient.trustManager(getTrustManagerFactory(truststoreBasedConfiguration, fipsCompliant)) - case Some(fileBasedConfiguration: ClientCertificateConfiguration.FileBasedConfiguration) => - SslContextBuilder.forClient.trustManager(getTrustedCertificatesFromPemFile(fileBasedConfiguration).toList.asJava) + sslSettings.clientCertificateSettings match { + case Some(truststoreBasedSettings: TruststoreBasedSettings) => + SslContextBuilder.forClient.trustManager(getTrustManagerFactory(truststoreBasedSettings, fipsCompliant)) + case Some(fileBasedSettings: ClientCertificateSettings.FileBasedSettings) => + SslContextBuilder.forClient.trustManager(getTrustedCertificatesFromPemFile(fileBasedSettings).toList.asJava) case None => throw new Exception("Client Authentication could not be enabled because trust certificates has not been configured") } @@ -82,21 +82,21 @@ object SSLCertHelper extends Logging { SslContextBuilder.forClient.trustManager(InsecureTrustManagerFactory.INSTANCE) } val result = if (fipsCompliant) { - val keystoreBasedConfiguration = sslConfiguration.serverCertificateConfiguration match { - case keystoreBasedConfiguration: KeystoreBasedConfiguration => keystoreBasedConfiguration - case _ => throw new Exception("KeyStore based configuration is required in FIPS compliant mode") + val keystoreBasedSettings = sslSettings.serverCertificateSettings match { + case keystoreBasedSettings: KeystoreBasedSettings => keystoreBasedSettings + case _ => throw new Exception("KeyStore based settings is required in FIPS compliant mode") } - getFipsCompliantKeyManagerFactory(keystoreBasedConfiguration) + getFipsCompliantKeyManagerFactory(keystoreBasedSettings) .map { keyManagerFactory => logger.info(s"Initializing ROR SSL using SSL provider: ${keyManagerFactory.getProvider.getName.show}") builder.keyManager(keyManagerFactory) } } else { - (sslConfiguration.serverCertificateConfiguration match { - case fileBasedConfiguration: ServerCertificateConfiguration.FileBasedConfiguration => - getPrivateKeyAndCertificateChainFromPemFiles(fileBasedConfiguration) - case keystoreBasedConfiguration: KeystoreBasedConfiguration => - getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedConfiguration) + (sslSettings.serverCertificateSettings match { + case fileBasedSettings: ServerCertificateSettings.FileBasedSettings => + getPrivateKeyAndCertificateChainFromPemFiles(fileBasedSettings) + case keystoreBasedSettings: KeystoreBasedSettings => + getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedSettings) }).map { case (privateKey, certificateChain) => logger.info(s"Initializing ROR SSL using default SSL provider ${SslContext.defaultServerProvider().name().show}") builder.keyManager(privateKey, certificateChain.toList.asJava) @@ -105,30 +105,30 @@ object SSLCertHelper extends Logging { result.unsafeRunSync().build() } - def prepareServerSSLContext(sslConfiguration: SslConfiguration, + def prepareServerSSLContext(sslSettings: SslSettings, fipsCompliant: Boolean, clientAuthenticationEnabled: Boolean): SslContext = { - prepareSslContextBuilder(sslConfiguration, fipsCompliant) + prepareSslContextBuilder(sslSettings, fipsCompliant) .attempt .map { case Right(sslCtxBuilder) => - areProtocolAndCiphersValid(sslCtxBuilder, sslConfiguration) - if (sslConfiguration.allowedCiphers.nonEmpty) { - sslCtxBuilder.ciphers(sslConfiguration.allowedCiphers.map(_.value).asJava) + areProtocolAndCiphersValid(sslCtxBuilder, sslSettings) + if (sslSettings.allowedCiphers.nonEmpty) { + sslCtxBuilder.ciphers(sslSettings.allowedCiphers.map(_.value).asJava) } if (clientAuthenticationEnabled) { sslCtxBuilder.clientAuth(ClientAuth.REQUIRE) - sslConfiguration.clientCertificateConfiguration match { - case Some(truststoreBasedConfiguration: TruststoreBasedConfiguration) => - sslCtxBuilder.trustManager(getTrustManagerFactory(truststoreBasedConfiguration, fipsCompliant)) - case Some(fileBasedConfiguration: ClientCertificateConfiguration.FileBasedConfiguration) => - sslCtxBuilder.trustManager(getTrustedCertificatesFromPemFile(fileBasedConfiguration).toList.asJava) + sslSettings.clientCertificateSettings match { + case Some(truststoreBasedSettings: TruststoreBasedSettings) => + sslCtxBuilder.trustManager(getTrustManagerFactory(truststoreBasedSettings, fipsCompliant)) + case Some(fileBasedSettings: ClientCertificateSettings.FileBasedSettings) => + sslCtxBuilder.trustManager(getTrustedCertificatesFromPemFile(fileBasedSettings).toList.asJava) case None => throw new Exception("Client Authentication could not be enabled because trust certificates has not been configured") } } - if (sslConfiguration.allowedProtocols.nonEmpty) { - sslCtxBuilder.protocols(sslConfiguration.allowedProtocols.map(_.value).asJava) + if (sslSettings.allowedProtocols.nonEmpty) { + sslCtxBuilder.protocols(sslSettings.allowedProtocols.map(_.value).asJava) } sslCtxBuilder.build() case Left(exception: IOException) => @@ -146,8 +146,8 @@ object SSLCertHelper extends Logging { .isSuccess } - def getTrustedCertificatesFromPemFile(fileBasedConfiguration: ClientCertificateConfiguration.FileBasedConfiguration): Array[X509Certificate] = { - loadCertificateChain(fileBasedConfiguration.clientTrustedCertificateFile.value) + private def getTrustedCertificatesFromPemFile(fileBasedSettings: ClientCertificateSettings.FileBasedSettings): Array[X509Certificate] = { + loadCertificateChain(fileBasedSettings.clientTrustedCertificateFile.value) .attempt .map { case Right(certificateChain) => certificateChain @@ -157,8 +157,8 @@ object SSLCertHelper extends Logging { .unsafeRunSync() } - def getTrustManagerFactory(truststoreBasedConfiguration: TruststoreBasedConfiguration, fipsCompliant: Boolean): TrustManagerFactory = { - loadTruststore(truststoreBasedConfiguration, fipsCompliant) + private def getTrustManagerFactory(truststoreBasedSettings: TruststoreBasedSettings, fipsCompliant: Boolean): TrustManagerFactory = { + loadTruststore(truststoreBasedSettings, fipsCompliant) .map { truststore => val tmf = getTrustManagerFactoryInstance(fipsCompliant) tmf.init(truststore) @@ -174,8 +174,8 @@ object SSLCertHelper extends Logging { } private def areProtocolAndCiphersValid(sslContextBuilder: SslContextBuilder, - config: SslConfiguration): Boolean = - trySetProtocolsAndCiphersInsideNewEngine(sslContextBuilder: SslContextBuilder, config) + sslSettings: SslSettings): Boolean = + trySetProtocolsAndCiphersInsideNewEngine(sslContextBuilder: SslContextBuilder, sslSettings) .fold( ex => { logger.error(s"ROR SSL: cannot validate SSL protocols and ciphers! ${ex.getClass.getSimpleName.show} : ${ex.getMessage.show}", ex) @@ -218,22 +218,22 @@ object SSLCertHelper extends Logging { } } - private def loadKeystore(keystoreBasedConfiguration: KeystoreBasedConfiguration, fipsCompliant: Boolean): IO[KeyStore] = { + private def loadKeystore(keystoreBasedSettings: KeystoreBasedSettings, fipsCompliant: Boolean): IO[KeyStore] = { for { _ <- IO(logger.info("Preparing keystore...")) - keystore <- loadKeystoreFromFile(keystoreBasedConfiguration.keystoreFile.value, keystoreBasedConfiguration.keystorePassword, fipsCompliant) + keystore <- loadKeystoreFromFile(keystoreBasedSettings.keystoreFile.value, keystoreBasedSettings.keystorePassword, fipsCompliant) } yield keystore } - private def loadTruststore(truststoreBasedConfiguration: TruststoreBasedConfiguration, fipsCompliant: Boolean): IO[KeyStore] = { + private def loadTruststore(truststoreBasedSettings: TruststoreBasedSettings, fipsCompliant: Boolean): IO[KeyStore] = { for { _ <- IO(logger.info("Preparing truststore...")) - truststore <- loadKeystoreFromFile(truststoreBasedConfiguration.truststoreFile.value, truststoreBasedConfiguration.truststorePassword, fipsCompliant) + truststore <- loadKeystoreFromFile(truststoreBasedSettings.truststoreFile.value, truststoreBasedSettings.truststorePassword, fipsCompliant) } yield truststore } - private def prepareAlias(keystore: KeyStore, config: KeystoreBasedConfiguration) = - config.keyAlias match { + private def prepareAlias(keystore: KeyStore, settings: KeystoreBasedSettings) = + settings.keyAlias match { case None if keystore.aliases().hasMoreElements => val firstAlias = keystore.aliases().nextElement() logger.info(s"ROR SSL: ssl.key_alias not configured, took first alias in keystore: ${firstAlias.show}") @@ -249,23 +249,23 @@ object SSLCertHelper extends Logging { unnecessaryAliases.foreach(keystore.deleteEntry) } - private def getFipsCompliantKeyManagerFactory(keystoreBasedConfiguration: KeystoreBasedConfiguration): IO[KeyManagerFactory] = { - loadKeystore(keystoreBasedConfiguration, fipsCompliant = true) + private def getFipsCompliantKeyManagerFactory(keystoreBasedSettings: KeystoreBasedSettings): IO[KeyManagerFactory] = { + loadKeystore(keystoreBasedSettings, fipsCompliant = true) .map { keystore => - if (keystoreBasedConfiguration.keyPass.isDefined) { - logger.warn("ROR configuration parameter key_pass is declared however it won't be used in this mode. In this case password for specific key MUST be the same as keystore password") + if (keystoreBasedSettings.keyPass.isDefined) { + logger.warn("ROR settings parameter key_pass is declared however it won't be used in this mode. In this case password for specific key MUST be the same as keystore password") } - removeAllAliasesFromKeystoreBesidesOne(keystore, prepareAlias(keystore, keystoreBasedConfiguration)) + removeAllAliasesFromKeystoreBesidesOne(keystore, prepareAlias(keystore, keystoreBasedSettings)) val kmf = getKeyManagerFactoryInstance(fipsCompliant = true) - kmf.init(keystore, keystoreBasedConfiguration.keystorePassword) + kmf.init(keystore, keystoreBasedSettings.keystorePassword) kmf } } - private def getPrivateKeyAndCertificateChainFromPemFiles(fileBasedConfiguration: ServerCertificateConfiguration.FileBasedConfiguration): IO[(PrivateKey, Array[X509Certificate])] = { + private def getPrivateKeyAndCertificateChainFromPemFiles(fileBasedSettings: ServerCertificateSettings.FileBasedSettings): IO[(PrivateKey, Array[X509Certificate])] = { for { - privateKey <- loadPrivateKey(fileBasedConfiguration.serverCertificateKeyFile.value) - certificateChain <- loadCertificateChain(fileBasedConfiguration.serverCertificateFile.value) + privateKey <- loadPrivateKey(fileBasedSettings.serverCertificateKeyFile.value) + certificateChain <- loadCertificateChain(fileBasedSettings.serverCertificateFile.value) } yield (privateKey, certificateChain) } @@ -296,11 +296,11 @@ object SSLCertHelper extends Logging { } } - private def getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedConfiguration: KeystoreBasedConfiguration): IO[(PrivateKey, Array[X509Certificate])] = { - loadKeystore(keystoreBasedConfiguration, fipsCompliant = false) + private def getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedSettings: KeystoreBasedSettings): IO[(PrivateKey, Array[X509Certificate])] = { + loadKeystore(keystoreBasedSettings, fipsCompliant = false) .map { keystore => - val alias = prepareAlias(keystore, keystoreBasedConfiguration) - val privateKey = keystore.getKey(alias, keystoreBasedConfiguration.keyPass.map(_.value.toCharArray).orNull) match { + val alias = prepareAlias(keystore, keystoreBasedSettings) + val privateKey = keystore.getKey(alias, keystoreBasedSettings.keyPass.map(_.value.toCharArray).orNull) match { case pk: PrivateKey => pk case _ => throw MalformedSslSettings(s"Configured key with alias=${alias.show} is not a private key") } @@ -313,37 +313,37 @@ object SSLCertHelper extends Logging { } private def trySetProtocolsAndCiphersInsideNewEngine(sslContextBuilder: SslContextBuilder, - config: SslConfiguration) = Try { + sslSettings: SslSettings) = Try { val sslEngine = sslContextBuilder.build().newEngine(ByteBufAllocator.DEFAULT) logger.info(s"ROR SSL: Available ciphers: ${sslEngine.getEnabledCipherSuites.toList.show}") - if (config.allowedCiphers.nonEmpty) { - sslEngine.setEnabledCipherSuites(config.allowedCiphers.map(_.value).toArray) + if (sslSettings.allowedCiphers.nonEmpty) { + sslEngine.setEnabledCipherSuites(sslSettings.allowedCiphers.map(_.value).toArray) logger.info(s"ROR SSL: Restricting to ciphers: ${sslEngine.getEnabledCipherSuites.toList.show}") } logger.info(s"ROR SSL: Available SSL protocols: ${sslEngine.getEnabledProtocols.toList.show}") - if (config.allowedProtocols.nonEmpty) { - sslEngine.setEnabledProtocols(config.allowedProtocols.map(_.value).toArray) + if (sslSettings.allowedProtocols.nonEmpty) { + sslEngine.setEnabledProtocols(sslSettings.allowedProtocols.map(_.value).toArray) logger.info(s"ROR SSL: Restricting to SSL protocols: ${sslEngine.getEnabledProtocols.toList.show}") } } - private def prepareSslContextBuilder(sslConfiguration: SslConfiguration, fipsCompliant: Boolean): IO[SslContextBuilder] = { + private def prepareSslContextBuilder(sslSettings: SslSettings, fipsCompliant: Boolean): IO[SslContextBuilder] = { if (fipsCompliant) { - val keystoreBasedConfiguration = sslConfiguration.serverCertificateConfiguration match { - case keystoreBasedConfiguration: KeystoreBasedConfiguration => keystoreBasedConfiguration - case _ => throw new Exception("KeyStore based configuration is required in FIPS compliant mode") + val keystoreBasedSettings = sslSettings.serverCertificateSettings match { + case keystoreBasedSettings: KeystoreBasedSettings => keystoreBasedSettings + case _ => throw new Exception("KeyStore based settings is required in FIPS compliant mode") } - getFipsCompliantKeyManagerFactory(keystoreBasedConfiguration) + getFipsCompliantKeyManagerFactory(keystoreBasedSettings) .map { keyManagerFactory => logger.info(s"Initializing ROR SSL using SSL provider: ${keyManagerFactory.getProvider.getName.show}") SslContextBuilder.forServer(keyManagerFactory) } } else { - (sslConfiguration.serverCertificateConfiguration match { - case fileBasedConfiguration: ServerCertificateConfiguration.FileBasedConfiguration => - getPrivateKeyAndCertificateChainFromPemFiles(fileBasedConfiguration) - case keystoreBasedConfiguration: KeystoreBasedConfiguration => - getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedConfiguration) + (sslSettings.serverCertificateSettings match { + case fileBasedSettings: ServerCertificateSettings.FileBasedSettings => + getPrivateKeyAndCertificateChainFromPemFiles(fileBasedSettings) + case keystoreBasedSettings: KeystoreBasedSettings => + getPrivateKeyAndCertificateChainFromKeystore(keystoreBasedSettings) }).map { case (privateKey, certificateChain) => logger.info(s"Initializing ROR SSL using default SSL provider ${SslContext.defaultServerProvider().name().show}") SslContextBuilder.forServer(privateKey, certificateChain.toList.asJava) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala index b4e5252e2d..9054edeeef 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/EnabledAccessControlListTests.scala @@ -154,7 +154,7 @@ class EnabledAccessControlListTests extends AnyWordSpec with MockFactory with In showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden", flsEngine = FlsEngine.default, - configurationIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), + settingsIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala index bae2307862..8a6d390396 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/user/UserDefinitionsValidatorTests.scala @@ -122,7 +122,7 @@ class UserDefinitionsValidatorTests extends AnyWordSpec with Matchers { showBasicAuthPrompt = false, forbiddenRequestMessage = "Forbidden", flsEngine = GlobalSettings.FlsEngine.default, - configurationIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))), + settingsIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = validationEnabled ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala index dd5a16862f..698cbafe07 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/GlobalSettingsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.accesscontrol.utils.{SyncDecoder, SyncDecoderCreator} class GlobalSettingsTests extends BaseDecoderTest(GlobalSettingsTests.decoder) { - "A global settings should be able to be loaded from config (in the 'readonlyrest.global_settings' section level)" when { + "A global settings should be able to be loaded from settings (in the 'readonlyrest.global_settings' section level)" when { "'prompt_for_basic_auth'" should { "be decoded with success" when { "enabled" in { @@ -39,8 +39,8 @@ class GlobalSettingsTests | global_settings: | prompt_for_basic_auth: true """.stripMargin, - assertion = config => - config.showBasicAuthPrompt should be(true) + assertion = settings => + settings.showBasicAuthPrompt should be(true) ) } "disabled" in { @@ -50,15 +50,15 @@ class GlobalSettingsTests | global_settings: | prompt_for_basic_auth: false """.stripMargin, - assertion = config => - config.showBasicAuthPrompt should be(false) + assertion = settings => + settings.showBasicAuthPrompt should be(false) ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.showBasicAuthPrompt should be(false) + assertion = settings => + settings.showBasicAuthPrompt should be(false) ) } } @@ -72,15 +72,15 @@ class GlobalSettingsTests | global_settings: | response_if_req_forbidden: custom_forbidden_response """.stripMargin, - assertion = config => - config.forbiddenRequestMessage should be("custom_forbidden_response") + assertion = settings => + settings.forbiddenRequestMessage should be("custom_forbidden_response") ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.forbiddenRequestMessage should be("Forbidden by ReadonlyREST") + assertion = settings => + settings.forbiddenRequestMessage should be("Forbidden by ReadonlyREST") ) } } @@ -94,8 +94,8 @@ class GlobalSettingsTests | global_settings: | fls_engine: lucene """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.Lucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.Lucene) ) } "es_with_lucene" in { @@ -105,8 +105,8 @@ class GlobalSettingsTests | global_settings: | fls_engine: es_with_lucene """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.ESWithLucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.ESWithLucene) ) } "es" in { @@ -116,15 +116,15 @@ class GlobalSettingsTests | global_settings: | fls_engine: es """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.ES) + assertion = settings => + settings.flsEngine should be(FlsEngine.ES) ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.flsEngine should be(FlsEngine.ESWithLucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.ESWithLucene) ) } } @@ -154,8 +154,8 @@ class GlobalSettingsTests | global_settings: | username_case_sensitivity: case_sensitive """.stripMargin, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Enabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Enabled) ) } "case insensitive" in { @@ -165,15 +165,15 @@ class GlobalSettingsTests | global_settings: | username_case_sensitivity: case_insensitive """.stripMargin, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Disabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Disabled) ) } "no defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Enabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Enabled) ) } } @@ -203,8 +203,8 @@ class GlobalSettingsTests | global_settings: | users_section_duplicate_usernames_detection: true """.stripMargin, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) ) } "disabled" in { @@ -214,22 +214,22 @@ class GlobalSettingsTests | global_settings: | users_section_duplicate_usernames_detection: false """.stripMargin, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(false) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(false) ) } "no defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) ) } } } } - "A global settings should be able to be loaded from config (in the 'readonlyrest' section level)" when { + "A global settings should be able to be loaded from settings (in the 'readonlyrest' section level)" when { "'prompt_for_basic_auth'" should { "be decoded with success" when { "enabled" in { @@ -238,8 +238,8 @@ class GlobalSettingsTests s""" | prompt_for_basic_auth: true """.stripMargin, - assertion = config => - config.showBasicAuthPrompt should be(true) + assertion = settings => + settings.showBasicAuthPrompt should be(true) ) } "disabled" in { @@ -248,15 +248,15 @@ class GlobalSettingsTests s""" | prompt_for_basic_auth: false """.stripMargin, - assertion = config => - config.showBasicAuthPrompt should be(false) + assertion = settings => + settings.showBasicAuthPrompt should be(false) ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.showBasicAuthPrompt should be(false) + assertion = settings => + settings.showBasicAuthPrompt should be(false) ) } } @@ -269,15 +269,15 @@ class GlobalSettingsTests s""" | response_if_req_forbidden: custom_forbidden_response """.stripMargin, - assertion = config => - config.forbiddenRequestMessage should be("custom_forbidden_response") + assertion = settings => + settings.forbiddenRequestMessage should be("custom_forbidden_response") ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.forbiddenRequestMessage should be("Forbidden by ReadonlyREST") + assertion = settings => + settings.forbiddenRequestMessage should be("Forbidden by ReadonlyREST") ) } } @@ -290,8 +290,8 @@ class GlobalSettingsTests s""" | fls_engine: lucene """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.Lucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.Lucene) ) } "es_with_lucene" in { @@ -300,8 +300,8 @@ class GlobalSettingsTests s""" | fls_engine: es_with_lucene """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.ESWithLucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.ESWithLucene) ) } "es" in { @@ -310,15 +310,15 @@ class GlobalSettingsTests s""" | fls_engine: es """.stripMargin, - assertion = config => - config.flsEngine should be(FlsEngine.ES) + assertion = settings => + settings.flsEngine should be(FlsEngine.ES) ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.flsEngine should be(FlsEngine.ESWithLucene) + assertion = settings => + settings.flsEngine should be(FlsEngine.ESWithLucene) ) } } @@ -346,8 +346,8 @@ class GlobalSettingsTests s""" | username_case_sensitivity: case_sensitive """.stripMargin, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Enabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Enabled) ) } "case insensitive" in { @@ -356,15 +356,15 @@ class GlobalSettingsTests s""" | username_case_sensitivity: case_insensitive """.stripMargin, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Disabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Disabled) ) } "no defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.userIdCaseSensitivity should be(CaseSensitivity.Enabled) + assertion = settings => + settings.userIdCaseSensitivity should be(CaseSensitivity.Enabled) ) } } @@ -392,8 +392,8 @@ class GlobalSettingsTests s""" | users_section_duplicate_usernames_detection: true """.stripMargin, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) ) } "disabled" in { @@ -402,15 +402,15 @@ class GlobalSettingsTests s""" | users_section_duplicate_usernames_detection: false """.stripMargin, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(false) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(false) ) } "not defined" in { assertDecodingSuccess( yaml = noCustomSettingsYaml, - assertion = config => - config.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) + assertion = settings => + settings.usersDefinitionDuplicateUsernamesValidationEnabled should be(true) ) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala index 0c8454babe..761bb2a54d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala @@ -37,7 +37,7 @@ class ImpersonationSettingsTests extends BaseDecoderTest( showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden by ReadonlyREST", flsEngine = FlsEngine.ES, - configurationIndex = RorSettingsIndex(fullIndexName(".readonlyrest")), + settingsIndex = RorSettingsIndex(fullIndexName(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala index c3e5ac5612..e846477451 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala @@ -38,7 +38,7 @@ class UsersRuleSettingsTests extends BaseRuleSettingsDecoderTest[UsersRule] { showBasicAuthPrompt = true, forbiddenRequestMessage = "Forbidden", flsEngine = FlsEngine.default, - configurationIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), + settingsIndex = RorSettingsIndex(IndexName.Full(".readonlyrest")), userIdCaseSensitivity = CaseSensitivity.Enabled, usersDefinitionDuplicateUsernamesValidationEnabled = true ), diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala similarity index 79% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala index 12ac042741..90d347578f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslConfigurationTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala @@ -22,13 +22,13 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile -import tech.beshu.ror.settings.es.SslConfiguration.* -import tech.beshu.ror.settings.es.SslConfiguration.ServerCertificateConfiguration.{FileBasedConfiguration, KeystoreBasedConfiguration} +import tech.beshu.ror.settings.es.SslSettings.* +import tech.beshu.ror.settings.es.SslSettings.ServerCertificateSettings.{FileBasedSettings, KeystoreBasedSettings} import tech.beshu.ror.settings.es.{MalformedSettings, RorSslSettings} import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.getResourcePath -class SslConfigurationTest +class SslSettingsTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = new SystemContext( @@ -40,7 +40,7 @@ class SslConfigurationTest "all properties contain at least one non-digit" in { val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_elasticsearch_config") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + case Some(ExternalSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -55,7 +55,7 @@ class SslConfigurationTest "some properties contains only digits" in { val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_elasticsearch_config_only_digits") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + case Some(ExternalSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("123456")) keyPass should be(KeyPass("12")) @@ -70,7 +70,7 @@ class SslConfigurationTest "server and client are configured using pem files" in { val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_pem_files") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + case Some(ExternalSslSettings(FileBasedSettings(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateSettings.FileBasedSettings(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => serverCertificateKeyFile.value.name should be("server_certificate_key.pem") serverCertificateFile.value.name should be("server_certificate.pem") clientTrustedCertificateFile.value.name should be("client_certificate.pem") @@ -84,7 +84,7 @@ class SslConfigurationTest "elasticsearch config file doesn't contain ROR ssl section" in { val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_readonlyrest_config") inside(ssl.externalSsl) { - case Some(ExternalSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => + case Some(ExternalSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -131,7 +131,7 @@ class SslConfigurationTest loadRorSslSettings(configFolderPath) shouldBe Left { MalformedSettings( s"Cannot load ROR SSL settings from file $expectedFilePath. " + - s"Cause: Field sets [server_certificate_key_file, server_certificate_file] and [keystore_file, keystore_pass, key_pass, key_alias] could not be present in the same configuration section") + s"Cause: Field sets [server_certificate_key_file, server_certificate_file] and [keystore_file, keystore_pass, key_pass, key_alias] could not be present in the same settings section") } } } @@ -141,7 +141,7 @@ class SslConfigurationTest "be loaded from elasticsearch config file" in { val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_elasticsearch_config") inside(ssl.internodeSsl) { - case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + case Some(InternodeSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), truststoreConfiguration, allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) @@ -157,7 +157,7 @@ class SslConfigurationTest "be loaded from elasticsearch config file when pem files are used" in { val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_pem_files") inside(ssl.internodeSsl) { - case Some(InternodeSslSettings(FileBasedConfiguration(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateConfiguration.FileBasedConfiguration(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + case Some(InternodeSslSettings(FileBasedSettings(serverCertificateKeyFile, serverCertificateFile), Some(ClientCertificateSettings.FileBasedSettings(clientTrustedCertificateFile)), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => serverCertificateKeyFile.value.name should be("server_certificate_key.pem") serverCertificateFile.value.name should be("server_certificate.pem") clientTrustedCertificateFile.value.name should be("client_certificate.pem") @@ -172,7 +172,7 @@ class SslConfigurationTest "elasticsearch config file doesn't contain ROR ssl section" in { val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_readonlyrest_config") inside(ssl.internodeSsl) { - case Some(InternodeSslSettings(KeystoreBasedConfiguration(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateConfiguration.TruststoreBasedConfiguration(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => + case Some(InternodeSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") keystorePassword should be(KeystorePassword("readonlyrest1")) keyPass should be(KeyPass("readonlyrest2")) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 0e58945176..38403cff0c 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslSettings +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index a62e3fa009..c42eb32d37 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslSettings +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort From e1757eff038d6215abc2da7693f394d6993d8652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 1 Oct 2025 18:06:05 +0200 Subject: [PATCH 037/103] refactoring --- .../accesscontrol/domain/elasticsearch.scala | 18 +-- .../main/scala/tech/beshu/ror/constants.scala | 19 +-- .../ActionYamlLoadedAccessControlTest.scala | 4 +- .../kibana/BaseKibanaAccessBasedTests.scala | 4 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 51 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++---- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 ---------- .../actions/rrconfig/RRConfigActionType.scala | 29 ----- .../es/actions/rrconfig/RRConfigRequest.java | 49 -------- .../es/actions/rrconfig/RRConfigsRequest.java | 34 ----- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ------------------ .../rrconfig/rest/RestRRConfigAction.scala | 56 --------- .../RestRRConfigActionResponseBuilder.scala | 65 ---------- .../RRTestSettingsActionHandler.scala | 16 +-- .../RRTestSettingsActionType.scala | 14 +-- .../RRTestSettingsRequest.scala | 22 ++-- .../RRTestSettingsResponse.scala | 22 ++-- .../TransportRRTestSettingsAction.scala | 18 +-- .../rest/RestRRTestSettingsAction.scala | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../es/services/EsIndexDocumentManager.scala | 49 ++++---- .../es/ssl/SSLNetty4HttpServerTransport.scala | 4 +- .../SSLNetty4InternodeServerTransport.scala | 4 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 4 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 8 +- .../rradmin/RRAdminActionHandler.scala | 2 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 8 +- .../es/actions/rradmin/RRAdminResponse.scala | 12 +- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../RRTestSettingsActionHandler.scala | 22 ++-- .../RRTestSettingsActionType.scala | 14 +-- .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 44 +++---- .../TransportRRTestSettingsAction.scala | 18 +-- .../rest/RestRRTestSettingsAction.scala | 16 +-- .../es/services/EsIndexDocumentManager.scala | 6 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 19 +-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++---- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 ---------- .../actions/rrconfig/RRConfigActionType.scala | 29 ----- .../es/actions/rrconfig/RRConfigRequest.java | 56 --------- .../es/actions/rrconfig/RRConfigsRequest.java | 34 ----- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ------------------ .../rrconfig/rest/RestRRConfigAction.scala | 56 --------- .../RestRRConfigActionResponseBuilder.scala | 65 ---------- .../RRTestSettingsActionHandler.scala | 22 ++-- .../RRTestSettingsActionType.scala | 14 +-- .../RRTestSettingsRequest.scala} | 34 ++--- .../RRTestSettingsResponse.scala | 44 +++---- .../TransportRRTestSettingsAction.scala | 18 +-- .../rest/RestRRTestSettingsAction.scala | 16 +-- .../es/handler/AclAwareRequestFilter.scala | 2 +- .../RorNotAvailableRequestHandler.scala | 10 +- .../es/services/EsIndexDocumentManager.scala | 49 ++++---- .../es/ssl/SSLNetty4HttpServerTransport.scala | 4 +- .../SSLNetty4InternodeServerTransport.scala | 4 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- settings.gradle | 2 +- 73 files changed, 474 insertions(+), 1416 deletions(-) delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala (77%) rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala (64%) rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (75%) rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (83%) rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (65%) rename es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (71%) rename es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (71%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala (69%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala (64%) rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (59%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (65%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (71%) delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala => es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala (69%) rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala => es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala (64%) rename es91x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigRequest.scala => rrtestsettings/RRTestSettingsRequest.scala} (59%) rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (65%) rename es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (71%) rename es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (71%) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/elasticsearch.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/elasticsearch.scala index f10ec24887..bbfa8ece6c 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/elasticsearch.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/elasticsearch.scala @@ -53,11 +53,11 @@ object Action { abstract sealed class AdminRorAction(override val value: String) extends RorAction(value) case object RorUserMetadataAction extends RoRorAction("cluster:internal_ror/user_metadata/get") - case object RorConfigAction extends AdminRorAction("cluster:internal_ror/config/manage") - case object RorTestConfigAction extends AdminRorAction("cluster:internal_ror/testconfig/manage") + case object RorMainSettingsAction extends AdminRorAction("cluster:internal_ror/config/manage") + case object RorTestSettingsAction extends AdminRorAction("cluster:internal_ror/testconfig/manage") case object RorAuthMockAction extends AdminRorAction("cluster:internal_ror/authmock/manage") case object RorAuditEventAction extends RwRorAction("cluster:internal_ror/audit_event/put") - case object RorOldConfigAction extends AdminRorAction("cluster:internal_ror/config/refreshsettings") + case object RorRefreshSettingsAction extends AdminRorAction("cluster:internal_ror/config/refreshsettings") def fromString(value: String): Option[Action] = { rorActionFrom(value) @@ -73,21 +73,21 @@ object Action { private def rorActionFrom(value: String): Option[RorAction] = value match { case RorUserMetadataAction.`value` => RorUserMetadataAction.some - case RorConfigAction.`value` => RorConfigAction.some - case RorTestConfigAction.`value` => RorTestConfigAction.some + case RorMainSettingsAction.`value` => RorMainSettingsAction.some + case RorTestSettingsAction.`value` => RorTestSettingsAction.some case RorAuthMockAction.`value` => RorAuthMockAction.some case RorAuditEventAction.`value` => RorAuditEventAction.some - case RorOldConfigAction.`value` => RorOldConfigAction.some + case RorRefreshSettingsAction.`value` => RorRefreshSettingsAction.some case _ => None } private val rorActionByOutdatedName: Map[String, RorAction] = Map( "cluster:ror/user_metadata/get" -> RorUserMetadataAction, - "cluster:ror/config/manage" -> RorConfigAction, - "cluster:ror/testconfig/manage" -> RorTestConfigAction, + "cluster:ror/config/manage" -> RorMainSettingsAction, + "cluster:ror/testconfig/manage" -> RorTestSettingsAction, "cluster:ror/authmock/manage" -> RorAuthMockAction, "cluster:ror/audit_event/put" -> RorAuditEventAction, - "cluster:ror/config/refreshsettings" -> RorOldConfigAction + "cluster:ror/config/refreshsettings" -> RorRefreshSettingsAction ) private def patternMatchingOutdatedRorActionName(possiblePattern: String): Option[EsAction] = { diff --git a/core/src/main/scala/tech/beshu/ror/constants.scala b/core/src/main/scala/tech/beshu/ror/constants.scala index 3b486c9d76..e1bc67bf8c 100644 --- a/core/src/main/scala/tech/beshu/ror/constants.scala +++ b/core/src/main/scala/tech/beshu/ror/constants.scala @@ -33,21 +33,22 @@ object constants { val CURRENT_USER_METADATA_PATH = "/_readonlyrest/metadata/current_user/" val AUDIT_EVENT_COLLECTOR_PATH = "/_readonlyrest/admin/audit/event/" - val FORCE_RELOAD_CONFIG_PATH = "/_readonlyrest/admin/refreshconfig/" - val UPDATE_INDEX_CONFIG_PATH = "/_readonlyrest/admin/config/" - val PROVIDE_TEST_CONFIG_PATH = "/_readonlyrest/admin/config/test/" - val UPDATE_TEST_CONFIG_PATH = "/_readonlyrest/admin/config/test/" - val DELETE_TEST_CONFIG_PATH = "/_readonlyrest/admin/config/test/" + val FORCE_RELOAD_SETTINGS_PATH = "/_readonlyrest/admin/refreshconfig/" + val UPDATE_INDEX_SETTINGS_PATH = "/_readonlyrest/admin/config/" + val PROVIDE_TEST_SETTINGS_PATH = "/_readonlyrest/admin/config/test/" + val UPDATE_TEST_SETTINGS_PATH = "/_readonlyrest/admin/config/test/" + val DELETE_TEST_SETTINGS_PATH = "/_readonlyrest/admin/config/test/" val PROVIDE_LOCAL_USERS_PATH = "/_readonlyrest/admin/config/test/localusers/" val CONFIGURE_AUTH_MOCK_PATH = "/_readonlyrest/admin/config/test/authmock/" val PROVIDE_AUTH_MOCK_PATH = "/_readonlyrest/admin/config/test/authmock/" - val PROVIDE_INDEX_CONFIG_PATH = "/_readonlyrest/admin/config/" - val PROVIDE_FILE_CONFIG_PATH = "/_readonlyrest/admin/config/file/" + val PROVIDE_INDEX_SETTINGS_PATH = "/_readonlyrest/admin/config/" + val PROVIDE_FILE_SETTINGS_PATH = "/_readonlyrest/admin/config/file/" val FIELDS_TRANSIENT = "_fields" - val FIELDS_ALWAYS_ALLOW: MutableSet[String] = - MutableSet("_id", "_uid", "_type", "_version", "_seq_no", "_primary_term", "_parent", "_routing", "_timestamp", "_ttl", "_size", "_index") + val FIELDS_ALWAYS_ALLOW: MutableSet[String] = MutableSet( + "_id", "_uid", "_type", "_version", "_seq_no", "_primary_term", "_parent", "_routing", "_timestamp", "_ttl", "_size", "_index" + ) val AUDIT_LOG_DEFAULT_INDEX_TEMPLATE = "'readonlyrest_audit-'yyyy-MM-dd" diff --git a/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala b/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala index cec26d3722..2f61583296 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/ActionYamlLoadedAccessControlTest.scala @@ -64,7 +64,7 @@ class ActionYamlLoadedAccessControlTest extends AnyWordSpec with BaseYamlLoadedA } } "it is a test config request and the action name match pattern on the configured list" in { - val request = MockRequestContext.indices.copy(action = Action.RorAction.RorTestConfigAction) + val request = MockRequestContext.indices.copy(action = Action.RorAction.RorTestSettingsAction) val result = acl.handleRegularRequest(request).runSyncUnsafe() inside(result.result) { case Allow(_, block) => block.name.value should be("Allowed for test config action") @@ -78,7 +78,7 @@ class ActionYamlLoadedAccessControlTest extends AnyWordSpec with BaseYamlLoadedA } } "it is a config request and the action name match pattern on the configured list with old name" in { - val request = MockRequestContext.indices.copy(action = Action.RorAction.RorConfigAction) + val request = MockRequestContext.indices.copy(action = Action.RorAction.RorMainSettingsAction) val result = acl.handleRegularRequest(request).runSyncUnsafe() inside(result.result) { case Allow(_, block) => block.name.value should be("Allowed for config action") diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/BaseKibanaAccessBasedTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/BaseKibanaAccessBasedTests.scala index 2252027489..406393f8ed 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/BaseKibanaAccessBasedTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/rules/kibana/BaseKibanaAccessBasedTests.scala @@ -257,12 +257,12 @@ abstract class BaseKibanaAccessBasedTests[RULE <: Rule : RuleName, SETTINGS] )() assertMatchRuleUsingIndicesRequest( settingsOf(KibanaAccess.Admin), - Action.RorAction.RorOldConfigAction, + Action.RorAction.RorRefreshSettingsAction, requestedIndices = Set(RequestedIndex(Local(rorIndex), excluded = false)) )() assertMatchRuleUsingIndicesRequest( settingsOf(KibanaAccess.Admin), - Action.RorAction.RorConfigAction, + Action.RorAction.RorMainSettingsAction, requestedIndices = Set(RequestedIndex(Local(rorIndex), excluded = false)) )() assertMatchRuleUsingIndicesRequest( diff --git a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cc1e9b5b8f..011b4e7216 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b19dd45353..0e49cccf98 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -47,27 +48,27 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +103,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -128,7 +129,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(client), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -162,14 +163,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -180,14 +180,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -205,8 +204,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +227,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 1ecc29436c..7770420170 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -32,10 +32,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 9e8b4485a2..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.injection.guice.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 6a9c7e16d3..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 31a5826de5..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig, Void]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 2892f898f9..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.rest.* -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import java.util -import java.util.function.Supplier -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 77% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index 753473156d..3fe2540c1b 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler @@ -27,32 +27,32 @@ import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } private def handle(result: Either[Throwable, TestSettingsResponse], - listener: ActionListener[RRTestConfigResponse]) + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 75% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index ff76a4d3ce..c690c5ecfd 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest @@ -25,33 +25,33 @@ import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestSettingsApi.TestSettingsRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( + new RRTestSettingsRequest( TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 83% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 5ef154b663..ad72c8e5cf 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput @@ -26,21 +26,21 @@ import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestSettings => provideConfigResponse match { - case res: ProvideTestSettings.CurrentTestSettings => currentConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestSettings => updateConfigResponse match { - case res: UpdateTestSettings.SuccessResponse => updateConfigSuccessResponseJson(builder, res) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestSettings => invalidateConfigResponse match { + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } @@ -75,7 +75,7 @@ class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) @@ -85,7 +85,7 @@ class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) @@ -94,7 +94,7 @@ class RRTestConfigResponse(response: TestSettingsApi.TestSettingsResponse) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 2d936937d3..d72dc8acfe 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index c2da8cabe9..500846af8d 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer @@ -22,29 +22,29 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 40ae6d97e0..c1c6c8a26b 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 0ff995d0f2..38403cff0c 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,7 +36,7 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, tracer: Tracer, diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..c42eb32d37 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,7 +42,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, + ssl: InternodeSslSettings, sharedGroupFactory: SharedGroupFactory, fipsCompliant: Boolean) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) diff --git a/es818x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es818x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index 6b7344e3ae..ff7bac1b75 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configDir(), - modulesPath = environment.modulesDir(), + configDir = File(environment.configDir()), + modulesDir = File(environment.modulesDir()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 254fd48408..2c10ed0012 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -68,7 +68,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(esConfig.boot) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName @@ -221,7 +221,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start(esConfig) + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index fe092771ec..121ea147d2 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -58,8 +58,8 @@ import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} @@ -203,7 +203,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -225,7 +225,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index cb70001ebe..3165661004 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -42,7 +42,7 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index 39d29c3160..7240997d62 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -38,13 +38,13 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => MainSettingsApi.MainSettingsRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index e2c2ac7402..42ef512263 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -30,20 +30,20 @@ class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: MainSettingsResponse.ForceReloadMainSettings => forceReloadConfig match { + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: MainSettingsResponse.ProvideIndexMainSettings => provideIndexConfig match { - case ProvideIndexMainSettings.MainSettings(rawConfig) => addResponseJson(builder, response.status, rawConfig) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: MainSettingsResponse.ProvideFileMainSettings => provideFileConfig match { - case ProvideFileMainSettings.MainSettings(rawConfig) => addResponseJson(builder, response.status, rawConfig) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: MainSettingsResponse.UpdateIndexMainSettings => updateIndexConfig match { + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 1ecc29436c..7770420170 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -32,10 +32,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 2d936937d3..d72dc8acfe 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index c2da8cabe9..500846af8d 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer @@ -22,29 +22,29 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 486545fa93..c1c6c8a26b 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -77,8 +77,8 @@ class EsIndexDocumentManager(client: NodeClient, } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(DocumentNotFound) case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) Left(DocumentUnreachable) @@ -115,8 +115,4 @@ class EsIndexDocumentManager(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index 6b7344e3ae..ff7bac1b75 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configDir(), - modulesPath = environment.modulesDir(), + configDir = File(environment.configDir()), + modulesDir = File(environment.modulesDir()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es91x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es91x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 8ecc9c9488..1b4bda121a 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -106,7 +107,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def createService(cluster: AuditCluster): IndexBasedAuditSinkService & DataStreamBasedAuditSinkService = { cluster match { case AuditCluster.LocalAuditCluster => - new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry), threadPool)(using environmentConfig.clock) + new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry), threadPool)(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } @@ -220,7 +221,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 91537d5537..22c06602ed 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -46,26 +46,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -96,20 +96,20 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -126,7 +126,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(client), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -160,14 +160,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -178,14 +177,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) } - ) + } .toMap .asJava } @@ -203,8 +201,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -226,8 +223,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 1ecc29436c..7770420170 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -32,10 +32,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 21317a9d83..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.injection.guice.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 426641ac63..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Objects; - -public class RRConfigRequest extends ActionRequest { - - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - this.nodeConfigRequest = Objects.requireNonNull(nodeConfigRequest); - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); // header - out.writeString(NodeConfigRequestSerializer.serialize(nodeConfigRequest)); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } -} \ No newline at end of file diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0db5eda205..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index c0aba7ad0b..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig, Void]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 59203f11f5..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.rest.* -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import java.util -import java.util.function.Supplier -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 5f1ba63898..0000000000 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 2d936937d3..d72dc8acfe 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index c2da8cabe9..500846af8d 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer @@ -22,29 +22,29 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala b/es91x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala index 2f6a3aac03..9365230fe3 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala @@ -75,7 +75,7 @@ import tech.beshu.ror.es.handler.request.context.types.repositories.* import tech.beshu.ror.es.handler.request.context.types.ror.* import tech.beshu.ror.es.handler.request.context.types.snapshots.* import tech.beshu.ror.es.handler.request.context.types.templates.* -import tech.beshu.ror.es.{AtEsLevelUpdateActionResponseListener, HidingInternalErrorDetailsRorActionListener, RorActionListener, RorClusterService, RorRestChannel} +import tech.beshu.ror.es.{HidingInternalErrorDetailsRorActionListener, RorActionListener, RorClusterService, RorRestChannel, AtEsLevelUpdateActionResponseListener} import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* diff --git a/es91x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es91x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..9c00906853 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 40ae6d97e0..c1c6c8a26b 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce17639c06..5b11452c83 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,7 +35,7 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, tracer: Tracer, diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..c42eb32d37 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,7 +42,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, + ssl: InternodeSslSettings, sharedGroupFactory: SharedGroupFactory, fipsCompliant: Boolean) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es91x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index 6b7344e3ae..ff7bac1b75 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configDir(), - modulesPath = environment.modulesDir(), + configDir = File(environment.configDir()), + modulesDir = File(environment.modulesDir()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/settings.gradle b/settings.gradle index 9104267352..30eb644da2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -58,7 +58,7 @@ include 'core' //include 'es814x' //include 'es815x' //include 'es816x' -//include 'es818x' +include 'es818x' include 'es90x' include 'es91x' include 'ror-tools-core' From b9684572edad2f1a4b1520037a63a8a5d81e99b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 2 Oct 2025 10:21:05 +0200 Subject: [PATCH 038/103] porting solution to other modules --- .../tech/beshu/ror/utils/SSLCertHelper.scala | 23 ++-- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 10 +- .../ror/es/actions/rrconfig/RRConfig.java | 63 --------- .../actions/rrconfig/RRConfigActionType.scala | 38 ----- .../es/actions/rrconfig/RRConfigReader.scala | 27 ---- .../es/actions/rrconfig/RRConfigRequest.java | 54 -------- .../es/actions/rrconfig/RRConfigsRequest.java | 64 --------- .../actions/rrconfig/RRConfigsResponse.java | 53 ------- .../rrconfig/RRConfigsResponseReader.scala | 27 ---- .../rrconfig/TransportRRConfigAction.scala | 124 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestSettingsActionHandler.scala} | 22 +-- .../RRTestSettingsActionType.scala} | 25 ++-- .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala} | 22 +-- .../rest/RestRRTestSettingsAction.scala} | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../services/EsIndexJsonContentService.scala | 123 ----------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 7 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 10 +- .../ror/es/actions/rrconfig/RRConfig.java | 63 --------- .../actions/rrconfig/RRConfigActionType.scala | 31 ----- .../es/actions/rrconfig/RRConfigReader.scala | 27 ---- .../es/actions/rrconfig/RRConfigRequest.java | 54 -------- .../es/actions/rrconfig/RRConfigsRequest.java | 64 --------- .../actions/rrconfig/RRConfigsResponse.java | 53 ------- .../rrconfig/RRConfigsResponseReader.scala | 27 ---- .../rrconfig/TransportRRConfigAction.scala | 114 --------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestSettingsActionHandler.scala} | 22 +-- .../RRTestSettingsActionType.scala | 16 +-- .../RRTestSettingsRequest.scala} | 34 ++--- .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala | 19 +-- .../rest/RestRRTestSettingsAction.scala | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 7 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../RRTestSettingsActionHandler.scala | 22 +-- .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 50 ++++--- .../TransportRRTestSettingsAction.scala | 19 +-- .../rest/RestRRTestSettingsAction.scala | 20 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../RRTestSettingsActionHandler.scala | 22 +-- .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 19 +-- .../rest/RestRRTestSettingsAction.scala | 20 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - ...ice.scala => EsIndexDocumentManager.scala} | 52 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala} | 20 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../types/ResolveIndexEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 12 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 124 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../TransportRRTestConfigAction.scala | 44 ------ .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala} | 20 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 124 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 10 +- .../ror/es/actions/rrconfig/RRConfig.java | 63 --------- .../actions/rrconfig/RRConfigActionType.scala | 31 ----- .../es/actions/rrconfig/RRConfigReader.scala | 27 ---- .../es/actions/rrconfig/RRConfigRequest.java | 54 -------- .../es/actions/rrconfig/RRConfigsRequest.java | 64 --------- .../actions/rrconfig/RRConfigsResponse.java | 53 ------- .../rrconfig/RRConfigsResponseReader.scala | 27 ---- .../rrconfig/TransportRRConfigAction.scala | 114 --------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../TransportRRTestConfigAction.scala | 44 ------ .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 16 +-- .../RRTestSettingsRequest.scala | 34 ++--- .../RRTestSettingsResponse.scala} | 46 +++---- .../TransportRRTestSettingsAction.scala | 19 +-- .../rest/RestRRTestSettingsAction.scala | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 7 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 10 +- .../ror/es/actions/rrconfig/RRConfig.java | 63 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigReader.scala | 27 ---- .../es/actions/rrconfig/RRConfigRequest.java | 54 -------- .../es/actions/rrconfig/RRConfigsRequest.java | 64 --------- .../actions/rrconfig/RRConfigsResponse.java | 53 ------- .../rrconfig/RRConfigsResponseReader.scala | 27 ---- .../rrconfig/TransportRRConfigAction.scala | 115 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 64 --------- .../TransportRRTestConfigAction.scala | 44 ------ .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala} | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 7 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 10 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 68 --------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../TransportRRTestConfigAction.scala | 44 ------ .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala} | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 7 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 12 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 56 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 60 -------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 120 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 129 ----------------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 129 +++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetTemplatesEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 122 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 46 +++---- .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 16 +-- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 49 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 123 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala} | 44 +++--- .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala} | 18 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../es/services/EsIndexDocumentManager.scala | 49 ++++--- .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala} | 44 +++--- .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala} | 18 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../GetSnapshotsEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 52 ++++--- .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala} | 14 +- .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala} | 44 +++--- .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala} | 18 ++- .../RorNotAvailableRequestHandler.scala | 10 +- .../GetSnapshotsEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala} | 14 +- .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala} | 44 +++--- .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../GetSnapshotsEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 35 ----- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 118 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 57 -------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 48 ------- .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala} | 14 +- .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 48 +++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- ...GetComponentTemplateEsRequestContext.scala | 2 +- .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 34 ----- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ---------------- .../rrconfig/rest/RestRRConfigAction.scala | 56 -------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala} | 14 +- .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- ...ice.scala => EsIndexDocumentManager.scala} | 49 ++++--- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 5 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 5 +- .../SSLNetty4InternodeServerTransport.scala | 10 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 128 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 52 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/IndexLevelActionFilter.scala | 13 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 50 ++++--- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++--- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 --------- .../actions/rrconfig/RRConfigActionType.scala | 29 ---- .../es/actions/rrconfig/RRConfigRequest.java | 49 ------- .../es/actions/rrconfig/RRConfigsRequest.java | 61 -------- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 125 ----------------- .../rrconfig/rest/RestRRConfigAction.scala | 70 ---------- .../RestRRConfigActionResponseBuilder.scala | 65 --------- .../RRTestConfigActionHandler.scala | 61 -------- .../rrtestconfig/RRTestConfigActionType.scala | 35 ----- .../rrtestconfig/RRTestConfigRequest.scala | 60 -------- .../rrtestconfig/RRTestConfigResponse.scala | 130 ------------------ .../TransportRRTestConfigAction.scala | 44 ------ .../rest/RestRRTestConfigAction.scala | 52 ------- .../RRTestSettingsActionHandler.scala | 61 ++++++++ .../RRTestSettingsActionType.scala | 35 +++++ .../RRTestSettingsRequest.scala | 60 ++++++++ .../RRTestSettingsResponse.scala | 130 ++++++++++++++++++ .../TransportRRTestSettingsAction.scala | 45 ++++++ .../rest/RestRRTestSettingsAction.scala | 50 +++++++ .../RorNotAvailableRequestHandler.scala | 10 +- .../types/MultiGetEsRequestContext.scala | 1 - .../es/services/EsIndexDocumentManager.scala | 118 ++++++++++++++++ .../services/EsIndexJsonContentService.scala | 122 ---------------- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 5 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 5 +- .../SSLNetty4InternodeServerTransport.scala | 10 +- .../beshu/ror/es/ReadonlyRestPlugin.scala | 8 +- .../es/ssl/SSLNetty4HttpServerTransport.scala | 5 +- .../SSLNetty4InternodeServerTransport.scala | 10 +- settings.gradle | 58 ++++---- 951 files changed, 13406 insertions(+), 28567 deletions(-) delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala rename es67x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionHandler.scala => rrtestsettings/RRTestSettingsActionHandler.scala} (69%) rename es67x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (57%) rename es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (60%) rename es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) rename es67x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (63%) rename es67x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (70%) rename es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala rename es70x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionHandler.scala => rrtestsettings/RRTestSettingsActionHandler.scala} (69%) rename es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala => es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala (68%) rename es70x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigRequest.scala => rrtestsettings/RRTestSettingsRequest.scala} (60%) rename es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) rename es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (63%) rename es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (70%) rename es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala => es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala (69%) create mode 100644 es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala rename es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (59%) rename es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (65%) rename es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (63%) rename es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (70%) rename es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala => es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala (69%) create mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala rename es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (59%) create mode 100644 es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala rename es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (63%) rename es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (70%) rename es711x/src/main/scala/tech/beshu/ror/es/services/{EsIndexJsonContentService.scala => EsIndexDocumentManager.scala} (70%) delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala create mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala rename es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (59%) create mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala rename es714x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (70%) create mode 100644 es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala create mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala rename es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (59%) rename es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) create mode 100644 es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala rename es716x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (70%) rename es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) create mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala rename es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala create mode 100644 es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala rename es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala => es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala (68%) rename es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala => es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala (60%) rename es72x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala => es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala (63%) rename es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (70%) create mode 100644 es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala rename es73x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (70%) create mode 100644 es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala rename es74x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (70%) create mode 100644 es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala => es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala (66%) create mode 100644 es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala rename es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala => es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala (71%) rename es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (71%) delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala create mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es811x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es811x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) rename es811x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (71%) rename es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (71%) delete mode 100644 es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala create mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es812x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es812x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) rename es812x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (71%) rename es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala => es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala (70%) delete mode 100644 es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala create mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala rename es813x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (64%) create mode 100644 es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es813x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es813x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) rename es813x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (71%) create mode 100644 es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala rename es814x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (64%) create mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala rename es814x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es814x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) create mode 100644 es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala rename es815x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (64%) create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala create mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala rename es816x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (64%) create mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala rename es816x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) create mode 100644 es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala rename es816x/src/main/scala/tech/beshu/ror/es/services/{EsIndexJsonContentService.scala => EsIndexDocumentManager.scala} (71%) delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala create mode 100644 es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala delete mode 100644 es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala diff --git a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala index 99b22268fe..b6e07c5180 100644 --- a/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala +++ b/core/src/main/scala/tech/beshu/ror/utils/SSLCertHelper.scala @@ -32,6 +32,7 @@ import tech.beshu.ror.settings.es.SslSettings.* import tech.beshu.ror.settings.es.SslSettings.ClientCertificateSettings.TruststoreBasedSettings import tech.beshu.ror.settings.es.SslSettings.ServerCertificateSettings.KeystoreBasedSettings import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import java.io.{FileInputStream, FileReader, IOException} import java.security.cert.{CertificateFactory, X509Certificate} @@ -65,14 +66,12 @@ object SSLCertHelper extends Logging { sslEngine } - def prepareClientSSLContext(sslSettings: SslSettings, - fipsCompliant: Boolean, - certificateVerificationEnabled: Boolean): SslContext = { + def prepareClientSSLContext(sslSettings: SslSettings): SslContext = { val builder = - if (certificateVerificationEnabled) { + if (sslSettings.certificateVerificationEnabled) { sslSettings.clientCertificateSettings match { case Some(truststoreBasedSettings: TruststoreBasedSettings) => - SslContextBuilder.forClient.trustManager(getTrustManagerFactory(truststoreBasedSettings, fipsCompliant)) + SslContextBuilder.forClient.trustManager(getTrustManagerFactory(truststoreBasedSettings, sslSettings.fipsMode.isSslFipsCompliant)) case Some(fileBasedSettings: ClientCertificateSettings.FileBasedSettings) => SslContextBuilder.forClient.trustManager(getTrustedCertificatesFromPemFile(fileBasedSettings).toList.asJava) case None => @@ -81,7 +80,7 @@ object SSLCertHelper extends Logging { } else { SslContextBuilder.forClient.trustManager(InsecureTrustManagerFactory.INSTANCE) } - val result = if (fipsCompliant) { + val result = if (sslSettings.fipsMode.isSslFipsCompliant) { val keystoreBasedSettings = sslSettings.serverCertificateSettings match { case keystoreBasedSettings: KeystoreBasedSettings => keystoreBasedSettings case _ => throw new Exception("KeyStore based settings is required in FIPS compliant mode") @@ -105,10 +104,8 @@ object SSLCertHelper extends Logging { result.unsafeRunSync().build() } - def prepareServerSSLContext(sslSettings: SslSettings, - fipsCompliant: Boolean, - clientAuthenticationEnabled: Boolean): SslContext = { - prepareSslContextBuilder(sslSettings, fipsCompliant) + def prepareServerSSLContext(sslSettings: SslSettings, clientAuthenticationEnabled: Boolean): SslContext = { + prepareSslContextBuilder(sslSettings) .attempt .map { case Right(sslCtxBuilder) => @@ -120,7 +117,7 @@ object SSLCertHelper extends Logging { sslCtxBuilder.clientAuth(ClientAuth.REQUIRE) sslSettings.clientCertificateSettings match { case Some(truststoreBasedSettings: TruststoreBasedSettings) => - sslCtxBuilder.trustManager(getTrustManagerFactory(truststoreBasedSettings, fipsCompliant)) + sslCtxBuilder.trustManager(getTrustManagerFactory(truststoreBasedSettings, sslSettings.fipsMode.isSslFipsCompliant)) case Some(fileBasedSettings: ClientCertificateSettings.FileBasedSettings) => sslCtxBuilder.trustManager(getTrustedCertificatesFromPemFile(fileBasedSettings).toList.asJava) case None => @@ -327,8 +324,8 @@ object SSLCertHelper extends Logging { } } - private def prepareSslContextBuilder(sslSettings: SslSettings, fipsCompliant: Boolean): IO[SslContextBuilder] = { - if (fipsCompliant) { + private def prepareSslContextBuilder(sslSettings: SslSettings): IO[SslContextBuilder] = { + if (sslSettings.fipsMode.isSslFipsCompliant) { val keystoreBasedSettings = sslSettings.serverCertificateSettings match { case keystoreBasedSettings: KeystoreBasedSettings => keystoreBasedSettings case _ => throw new Exception("KeyStore based settings is required in FIPS compliant mode") diff --git a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cd75902e1b..b791d55d2d 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -213,7 +214,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index e6b51b65bd..b7b3132efd 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,16 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) xContentRegistry: NamedXContentRegistry, networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl) } - ) + } .toMap .asJava } @@ -186,16 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -208,8 +202,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +222,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(settings, restController), new RestRRAuthMockAction(settings, restController), - new RestRRTestConfigAction(settings, restController), - new RestRRConfigAction(settings, restController, nodesInCluster), + new RestRRTestSettingsAction(settings, restController), new RestRRUserMetadataAction(settings, restController), new RestRRAuditEventAction(settings, restController) ).asJava diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index e4e2a2c4be..8c4d3593e0 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -27,7 +27,7 @@ class RRAdminActionType extends Action[RRAdminRequest, RRAdminResponse, RRAdminR override def newResponse(): RRAdminResponse = new RRAdminResponse } object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index 4d3619d24f..e1486b99b6 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") def this() = { @@ -42,19 +42,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7e32e42c62..cb8e25ab99 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -19,11 +19,11 @@ package tech.beshu.ror.es.actions.rradmin import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -32,24 +32,24 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index b049809692..18b5e7ffa1 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.es.actions.rradmin.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.settings.Settings -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, RRAdminRequest, RRAdminResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @@ -29,10 +29,10 @@ import tech.beshu.ror.es.utils.RestToXContentWithStatusListener class RestRRAdminAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("POST", constants.FORCE_RELOAD_CONFIG_PATH) - register("GET", constants.PROVIDE_INDEX_CONFIG_PATH) - register("POST", constants.UPDATE_INDEX_CONFIG_PATH) - register("GET", constants.PROVIDE_FILE_CONFIG_PATH) + register("POST", constants.FORCE_RELOAD_SETTINGS_PATH) + register("GET", constants.PROVIDE_INDEX_SETTINGS_PATH) + register("POST", constants.UPDATE_INDEX_SETTINGS_PATH) + register("GET", constants.PROVIDE_FILE_SETTINGS_PATH) override val getName: String = "ror-admin-handler" diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 042bd0cf4d..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private NodeConfig nodeConfig; - - public RRConfig() { - super(); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 5bf1c513d9..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.{Action, ActionRequestBuilder} -import org.elasticsearch.client.ElasticsearchClient -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends Action[RRConfigsRequest, RRConfigsResponse, RRConfigActionType.RequestBuilder](RRConfigActionType.name) { - override def newResponse(): RRConfigsResponse = new RRConfigsResponse - - override def newRequestBuilder(client: ElasticsearchClient): RRConfigActionType.RequestBuilder = - new RRConfigActionType.RequestBuilder(client, this, new RRConfigsRequest()) -} - -object RRConfigActionType { - class RequestBuilder(client: ElasticsearchClient, rRConfigAction: RRConfigActionType, request: RRConfigsRequest) - extends ActionRequestBuilder[RRConfigsRequest, RRConfigsResponse, RequestBuilder](client, rRConfigAction, request) - - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = RRConfigsResponseReader -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala deleted file mode 100644 index 03e7017e59..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigReader extends Writeable.Reader[RRConfig] { - override def read(in: StreamInput): RRConfig = { - val response = new RRConfig - response.readFrom(in) - response - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 4df2ed9fce..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(String nodeId, NodeConfigRequest nodeConfigRequest) { - super(nodeId); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest() { - super(); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0da3e50dd5..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private NodeConfigRequest nodeConfigRequest; - - public RRConfigsRequest() { - super(); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 812d77e4ca..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse() { - super(); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfigReader::read); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } - -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala deleted file mode 100644 index 226e15cefe..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigsResponseReader extends Writeable.Reader[RRConfigsResponse] { - override def read(in: StreamInput): RRConfigsResponse = { - val response = new RRConfigsResponse - response.readNodesFrom(in) - response - } -} \ No newline at end of file diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 41b53f471f..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.settings.Settings -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(setting: Settings, - actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeExecutor: String, - indexNameExpressionResolver: IndexNameExpressionResolver, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - setting, - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - indexNameExpressionResolver, - () => new RRConfigsRequest(), - () => new RRConfigRequest(), - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(setting: Settings, - actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - indexNameExpressionResolver: IndexNameExpressionResolver, - ) = - this( - setting, - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - ThreadPool.Names.GENERIC, - indexNameExpressionResolver, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(): RRConfig = new RRConfig() - - override def newNodeRequest(nodeId: String, request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(nodeId, request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index e391a67490..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.settings.Settings -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(settings: Settings, - controller: RestController, - nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler(settings) { - - register("GET", constants.MANAGE_ROR_CONFIG_PATH) - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - - private def register(method: String, path: String): Unit = - controller.registerHandler(RestRequest.Method.valueOf(method), path, this) -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 57% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 1030bdbc81..219f633a33 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,27 +14,26 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{Action, ActionRequestBuilder} import org.elasticsearch.client.ElasticsearchClient import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends Action[RRTestConfigRequest, RRTestConfigResponse, RRTestConfigActionType.RequestBuilder]( - RRTestConfigActionType.name +class RRTestSettingsActionType extends Action[RRTestSettingsRequest, RRTestSettingsResponse, RRTestSettingsActionType.RequestBuilder]( + RRTestSettingsActionType.name ) { - override def newResponse(): RRTestConfigResponse = new RRTestConfigResponse() + override def newResponse(): RRTestSettingsResponse = new RRTestSettingsResponse() - override def newRequestBuilder(client: ElasticsearchClient): RRTestConfigActionType.RequestBuilder = - new RRTestConfigActionType.RequestBuilder(client, this, new RRTestConfigRequest()) + override def newRequestBuilder(client: ElasticsearchClient): RRTestSettingsActionType.RequestBuilder = + new RRTestSettingsActionType.RequestBuilder(client, this, new RRTestSettingsRequest()) } -object RRTestConfigActionType { - class RequestBuilder(client: ElasticsearchClient, actionType: RRTestConfigActionType, request: RRTestConfigRequest) - extends ActionRequestBuilder[RRTestConfigRequest, RRTestConfigResponse, RequestBuilder](client, actionType, request) - - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() -} +object RRTestSettingsActionType { + class RequestBuilder(client: ElasticsearchClient, actionType: RRTestSettingsActionType, request: RRTestSettingsRequest) + extends ActionRequestBuilder[RRTestSettingsRequest, RRTestSettingsResponse, RequestBuilder](client, actionType, request) + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() +} \ No newline at end of file diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 60% rename from es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index 095a027ee9..3021184f9c 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,49 +14,49 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { def this() = { this(null, null) } - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3af2f7fc7c..ac79fb48e1 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,18 +14,18 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -34,18 +34,18 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -61,10 +61,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -78,26 +78,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 63% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 473af7fb41..d472bba9a6 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,14 +26,14 @@ import org.elasticsearch.transport.TransportService import scala.annotation.unused -class TransportRRTestConfigAction(settings: Settings, - threadPool: ThreadPool, - transportService: TransportService, - actionFilters: ActionFilters, - indexNameExpressionResolver: IndexNameExpressionResolver, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - settings, RRTestConfigActionType.name, threadPool, transportService, actionFilters, indexNameExpressionResolver, () => new RRTestConfigRequest() +class TransportRRTestSettingsAction(settings: Settings, + threadPool: ThreadPool, + transportService: TransportService, + actionFilters: ActionFilters, + indexNameExpressionResolver: IndexNameExpressionResolver, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + settings, RRTestSettingsActionType.name, threadPool, transportService, actionFilters, indexNameExpressionResolver, () => new RRTestSettingsRequest() ) { @Inject @@ -45,9 +45,9 @@ class TransportRRTestConfigAction(settings: Settings, this(settings, threadPool, transportService, actionFilters, indexNameExpressionResolver, ()) } - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 4fcf252c1f..ccdf13ac89 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject @@ -22,25 +22,25 @@ import org.elasticsearch.common.settings.Settings import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @Inject -class RestRRTestConfigAction(settings: Settings, controller: RestController) +class RestRRTestSettingsAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("GET", constants.PROVIDE_TEST_CONFIG_PATH) - register("POST", constants.UPDATE_TEST_CONFIG_PATH) - register("DELETE", constants.DELETE_TEST_CONFIG_PATH) + register("GET", constants.PROVIDE_TEST_SETTINGS_PATH) + register("POST", constants.UPDATE_TEST_SETTINGS_PATH) + register("DELETE", constants.DELETE_TEST_SETTINGS_PATH) register("GET", constants.PROVIDE_LOCAL_USERS_PATH) override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index e70885582e..368597ae85 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -107,7 +107,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 18490a232c..e7f5ac4866 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index a6c3824699..0000000000 --- a/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setType("settings") - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 46540f37ef..60e4b0b852 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,12 +35,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - fipsCompliant: Boolean) + ssl: ExternalSslSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es67x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cd75902e1b..b791d55d2d 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -213,7 +214,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4b93c1ebc4..51d170eff0 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,16 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) xContentRegistry: NamedXContentRegistry, networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl) } - ) + } .toMap .asJava } @@ -186,16 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -208,8 +202,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +222,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(settings, restController), new RestRRAuthMockAction(settings, restController), - new RestRRTestConfigAction(settings, restController), - new RestRRConfigAction(settings, restController, nodesInCluster), + new RestRRTestSettingsAction(settings, restController), new RestRRUserMetadataAction(settings, restController), new RestRRAuditEventAction(settings, restController) ).asJava diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index fae036b440..b8c818b3b2 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,6 +23,6 @@ class RRAdminActionType extends Action[RRAdminResponse](RRAdminActionType.name) override def newResponse(): RRAdminResponse = new RRAdminResponse } object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() } \ No newline at end of file diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index 4d3619d24f..e1486b99b6 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") def this() = { @@ -42,19 +42,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7e32e42c62..cb8e25ab99 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -19,11 +19,11 @@ package tech.beshu.ror.es.actions.rradmin import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -32,24 +32,24 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index b049809692..18b5e7ffa1 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.es.actions.rradmin.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.settings.Settings -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, RRAdminRequest, RRAdminResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @@ -29,10 +29,10 @@ import tech.beshu.ror.es.utils.RestToXContentWithStatusListener class RestRRAdminAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("POST", constants.FORCE_RELOAD_CONFIG_PATH) - register("GET", constants.PROVIDE_INDEX_CONFIG_PATH) - register("POST", constants.UPDATE_INDEX_CONFIG_PATH) - register("GET", constants.PROVIDE_FILE_CONFIG_PATH) + register("POST", constants.FORCE_RELOAD_SETTINGS_PATH) + register("GET", constants.PROVIDE_INDEX_SETTINGS_PATH) + register("POST", constants.UPDATE_INDEX_SETTINGS_PATH) + register("GET", constants.PROVIDE_FILE_SETTINGS_PATH) override val getName: String = "ror-admin-handler" diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 042bd0cf4d..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private NodeConfig nodeConfig; - - public RRConfig() { - super(); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index d9b3f9a332..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.Action -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends Action[RRConfigsResponse](RRConfigActionType.name) { - override def newResponse(): RRConfigsResponse = new RRConfigsResponse -} - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = RRConfigsResponseReader -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala deleted file mode 100644 index 03e7017e59..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigReader extends Writeable.Reader[RRConfig] { - override def read(in: StreamInput): RRConfig = { - val response = new RRConfig - response.readFrom(in) - response - } -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 4df2ed9fce..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(String nodeId, NodeConfigRequest nodeConfigRequest) { - super(nodeId); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest() { - super(); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0da3e50dd5..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private NodeConfigRequest nodeConfigRequest; - - public RRConfigsRequest() { - super(); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 812d77e4ca..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse() { - super(); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfigReader::read); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } - -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala deleted file mode 100644 index 226e15cefe..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigsResponseReader extends Writeable.Reader[RRConfigsResponse] { - override def read(in: StreamInput): RRConfigsResponse = { - val response = new RRConfigsResponse - response.readNodesFrom(in) - response - } -} \ No newline at end of file diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 58fdfcf958..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - () => new RRConfigsRequest(), - () => new RRConfigRequest(), - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(nodeId: String, request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(nodeId, request.getNodeConfigRequest) - - override def newNodeResponse(): RRConfig = new RRConfig() - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index e391a67490..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.settings.Settings -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(settings: Settings, - controller: RestController, - nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler(settings) { - - register("GET", constants.MANAGE_ROR_CONFIG_PATH) - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - - private def register(method: String, path: String): Unit = - controller.registerHandler(RestRequest.Method.valueOf(method), path, this) -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 68% rename from es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 1de3a2d3e6..24b98902d8 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,17 +14,17 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.Action import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends Action[RRTestConfigResponse](RRTestConfigActionType.name) { - override def newResponse(): RRTestConfigResponse = - new RRTestConfigResponse() +class RRTestSettingsActionType extends Action[RRTestSettingsResponse](RRTestSettingsActionType.name) { + override def newResponse(): RRTestSettingsResponse = + new RRTestSettingsResponse() } -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() -} +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() +} \ No newline at end of file diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 60% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index 095a027ee9..3021184f9c 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,49 +14,49 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { def this() = { this(null, null) } - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3af2f7fc7c..ac79fb48e1 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,18 +14,18 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -34,18 +34,18 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -61,10 +61,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -78,26 +78,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 63% rename from es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 688fd79e44..748b3b944a 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -24,21 +24,22 @@ import org.elasticsearch.transport.TransportService import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, () => new RRTestSettingsRequest() ) { @Inject def this(transportService: TransportService, - actionFilters: ActionFilters) = + actionFilters: ActionFilters) = { this(transportService, actionFilters, ()) + } - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 4fcf252c1f..ccdf13ac89 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject @@ -22,25 +22,25 @@ import org.elasticsearch.common.settings.Settings import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @Inject -class RestRRTestConfigAction(settings: Settings, controller: RestController) +class RestRRTestSettingsAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("GET", constants.PROVIDE_TEST_CONFIG_PATH) - register("POST", constants.UPDATE_TEST_CONFIG_PATH) - register("DELETE", constants.DELETE_TEST_CONFIG_PATH) + register("GET", constants.PROVIDE_TEST_SETTINGS_PATH) + register("POST", constants.UPDATE_TEST_SETTINGS_PATH) + register("DELETE", constants.DELETE_TEST_SETTINGS_PATH) register("GET", constants.PROVIDE_LOCAL_USERS_PATH) override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index 57fcf6f6c1..0bdf0ce63d 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 18490a232c..e7f5ac4866 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d3b8accded..942c9d37cd 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,12 +35,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - fipsCompliant: Boolean) + ssl: ExternalSslSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es70x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es70x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 0e96c82c0e..1c63128a26 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 7c10baf5be..b92a933cfa 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,26 +51,25 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -237,8 +234,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 4720e2a6cf..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 65% rename from es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3af2f7fc7c..16e8851da7 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,38 +14,34 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { - def this() = { - this(null) - } - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -61,10 +57,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -78,26 +74,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 63% rename from es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 688fd79e44..35e40b8f73 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -24,21 +24,22 @@ import org.elasticsearch.transport.TransportService import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader ) { @Inject def this(transportService: TransportService, - actionFilters: ActionFilters) = + actionFilters: ActionFilters) = { this(transportService, actionFilters, ()) + } - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 74c96fdf67..26e9e92cb0 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject +import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index aa52fe4beb..c170a8c87d 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetadata], + def filter(templates: Iterable[IndexTemplateMetadata], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetadata] = { val templatesMap = templates diff --git a/es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 18490a232c..e7f5ac4866 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 3fb7bb8b1b..d30183cb08 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es710x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es710x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 0e96c82c0e..1c63128a26 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 7c10baf5be..b92a933cfa 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,26 +51,25 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -237,8 +234,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 4720e2a6cf..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 63% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 47733a387e..35e40b8f73 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -24,21 +24,22 @@ import org.elasticsearch.transport.TransportService import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, () => new RRTestConfigRequest() +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader ) { @Inject def this(transportService: TransportService, - actionFilters: ActionFilters) = + actionFilters: ActionFilters) = { this(transportService, actionFilters, ()) + } - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 74c96fdf67..26e9e92cb0 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject +import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es711x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es711x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 18490a232c..e7f5ac4866 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 3fb7bb8b1b..d30183cb08 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es711x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es711x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 0e96c82c0e..1c63128a26 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 7c10baf5be..b92a933cfa 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,26 +51,25 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -237,8 +234,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index ac1ad056c8..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 74c96fdf67..26e9e92cb0 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject +import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala b/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala index 50924b1f97..f96a05bb31 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala @@ -23,7 +23,6 @@ import org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.{Resolv import org.elasticsearch.threadpool.ThreadPool import org.joor.Reflect.* import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.{ClusterIndexName, RequestedIndex} import tech.beshu.ror.es.RorClusterService import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext diff --git a/es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es714x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 3fb7bb8b1b..d30183cb08 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es714x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es714x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 349b753160..d3f1c12ba2 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -36,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -61,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -225,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8786797691..ed82d9aa2b 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -50,26 +51,25 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.{SystemContext, constants} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -237,8 +234,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 321a6aa0b9..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index ac1ad056c8..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3426623ea9..e15d4f329a 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -58,10 +58,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 74c96fdf67..26e9e92cb0 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject +import org.elasticsearch.rest.* import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es716x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es716x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 2a9a3dfd8f..71f6ba880d 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2a9a3dfd8f..0000000000 --- a/es716x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 2b457c7103..e9130b487e 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es716x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es716x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index aa1fc13e4e..d3f1c12ba2 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 940a0c4f19..95ed0bf071 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -38,8 +39,8 @@ import org.elasticsearch.http.{HttpPreRequest, HttpServerTransport} import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,26 +51,25 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -174,14 +174,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) dispatcher: HttpServerTransport.Dispatcher, perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -192,14 +191,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -217,8 +215,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -238,8 +235,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 321a6aa0b9..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index ac1ad056c8..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 74c96fdf67..0000000000 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3426623ea9..e15d4f329a 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -58,10 +58,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..26e9e92cb0 --- /dev/null +++ b/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es717x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es717x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 2a9a3dfd8f..71f6ba880d 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 3638642e19..991356d628 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es717x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es717x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cd75902e1b..b791d55d2d 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -213,7 +214,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4b93c1ebc4..51d170eff0 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,16 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) xContentRegistry: NamedXContentRegistry, networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl) } - ) + } .toMap .asJava } @@ -186,16 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -208,8 +202,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +222,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(settings, restController), new RestRRAuthMockAction(settings, restController), - new RestRRTestConfigAction(settings, restController), - new RestRRConfigAction(settings, restController, nodesInCluster), + new RestRRTestSettingsAction(settings, restController), new RestRRUserMetadataAction(settings, restController), new RestRRAuditEventAction(settings, restController) ).asJava diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index fae036b440..b8c818b3b2 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,6 +23,6 @@ class RRAdminActionType extends Action[RRAdminResponse](RRAdminActionType.name) override def newResponse(): RRAdminResponse = new RRAdminResponse } object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() } \ No newline at end of file diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index 4d3619d24f..e1486b99b6 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") def this() = { @@ -42,19 +42,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7e32e42c62..cb8e25ab99 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -19,11 +19,11 @@ package tech.beshu.ror.es.actions.rradmin import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -32,24 +32,24 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index b049809692..18b5e7ffa1 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.es.actions.rradmin.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.settings.Settings -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, RRAdminRequest, RRAdminResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @@ -29,10 +29,10 @@ import tech.beshu.ror.es.utils.RestToXContentWithStatusListener class RestRRAdminAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("POST", constants.FORCE_RELOAD_CONFIG_PATH) - register("GET", constants.PROVIDE_INDEX_CONFIG_PATH) - register("POST", constants.UPDATE_INDEX_CONFIG_PATH) - register("GET", constants.PROVIDE_FILE_CONFIG_PATH) + register("POST", constants.FORCE_RELOAD_SETTINGS_PATH) + register("GET", constants.PROVIDE_INDEX_SETTINGS_PATH) + register("POST", constants.UPDATE_INDEX_SETTINGS_PATH) + register("GET", constants.PROVIDE_FILE_SETTINGS_PATH) override val getName: String = "ror-admin-handler" diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 042bd0cf4d..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private NodeConfig nodeConfig; - - public RRConfig() { - super(); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index d9b3f9a332..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.Action -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends Action[RRConfigsResponse](RRConfigActionType.name) { - override def newResponse(): RRConfigsResponse = new RRConfigsResponse -} - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = RRConfigsResponseReader -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala deleted file mode 100644 index 03e7017e59..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigReader extends Writeable.Reader[RRConfig] { - override def read(in: StreamInput): RRConfig = { - val response = new RRConfig - response.readFrom(in) - response - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 4df2ed9fce..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(String nodeId, NodeConfigRequest nodeConfigRequest) { - super(nodeId); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest() { - super(); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0da3e50dd5..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private NodeConfigRequest nodeConfigRequest; - - public RRConfigsRequest() { - super(); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 812d77e4ca..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse() { - super(); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfigReader::read); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } - -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala deleted file mode 100644 index 226e15cefe..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigsResponseReader extends Writeable.Reader[RRConfigsResponse] { - override def read(in: StreamInput): RRConfigsResponse = { - val response = new RRConfigsResponse - response.readNodesFrom(in) - response - } -} \ No newline at end of file diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 58fdfcf958..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - () => new RRConfigsRequest(), - () => new RRConfigRequest(), - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(nodeId: String, request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(nodeId, request.getNodeConfigRequest) - - override def newNodeResponse(): RRConfig = new RRConfig() - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index e391a67490..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.settings.Settings -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(settings: Settings, - controller: RestController, - nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler(settings) { - - register("GET", constants.MANAGE_ROR_CONFIG_PATH) - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - - private def register(method: String, path: String): Unit = - controller.registerHandler(RestRequest.Method.valueOf(method), path, this) -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 47733a387e..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, () => new RRTestConfigRequest() - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 68% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 1de3a2d3e6..24b98902d8 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,17 +14,17 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.Action import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends Action[RRTestConfigResponse](RRTestConfigActionType.name) { - override def newResponse(): RRTestConfigResponse = - new RRTestConfigResponse() +class RRTestSettingsActionType extends Action[RRTestSettingsResponse](RRTestSettingsActionType.name) { + override def newResponse(): RRTestSettingsResponse = + new RRTestSettingsResponse() } -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() -} +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() +} \ No newline at end of file diff --git a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 60% rename from es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index 095a027ee9..3021184f9c 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,49 +14,49 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { def this() = { this(null, null) } - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3af2f7fc7c..ac79fb48e1 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,18 +14,18 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { def this() = { @@ -34,18 +34,18 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -61,10 +61,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -78,26 +78,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 63% rename from es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 688fd79e44..748b3b944a 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -24,21 +24,22 @@ import org.elasticsearch.transport.TransportService import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, () => new RRTestSettingsRequest() ) { @Inject def this(transportService: TransportService, - actionFilters: ActionFilters) = + actionFilters: ActionFilters) = { this(transportService, actionFilters, ()) + } - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 4fcf252c1f..ccdf13ac89 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject @@ -22,25 +22,25 @@ import org.elasticsearch.common.settings.Settings import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @Inject -class RestRRTestConfigAction(settings: Settings, controller: RestController) +class RestRRTestSettingsAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("GET", constants.PROVIDE_TEST_CONFIG_PATH) - register("POST", constants.UPDATE_TEST_CONFIG_PATH) - register("DELETE", constants.DELETE_TEST_CONFIG_PATH) + register("GET", constants.PROVIDE_TEST_SETTINGS_PATH) + register("POST", constants.UPDATE_TEST_SETTINGS_PATH) + register("DELETE", constants.DELETE_TEST_SETTINGS_PATH) register("GET", constants.PROVIDE_LOCAL_USERS_PATH) override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index 57fcf6f6c1..0bdf0ce63d 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es72x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d3b8accded..942c9d37cd 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,12 +35,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - fipsCompliant: Boolean) + ssl: ExternalSslSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es72x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es72x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cd75902e1b..b791d55d2d 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -213,7 +214,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index aad5fc129a..5d63c3a201 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,16 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) xContentRegistry: NamedXContentRegistry, networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl) } - ) + } .toMap .asJava } @@ -186,16 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -208,8 +202,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +222,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(settings, restController), new RestRRAuthMockAction(settings, restController), - new RestRRTestConfigAction(settings, restController), - new RestRRConfigAction(settings, restController, nodesInCluster), + new RestRRTestSettingsAction(settings, restController), new RestRRUserMetadataAction(settings, restController), new RestRRAuditEventAction(settings, restController) ).asJava diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index 4d3619d24f..e1486b99b6 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") def this() = { @@ -42,19 +42,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index d36f58a813..7edb7a7c90 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -19,33 +19,33 @@ package tech.beshu.ror.es.actions.rradmin import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -54,10 +54,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index b049809692..18b5e7ffa1 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -19,8 +19,8 @@ package tech.beshu.ror.es.actions.rradmin.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject import org.elasticsearch.common.settings.Settings -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import tech.beshu.ror.constants import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, RRAdminRequest, RRAdminResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @@ -29,10 +29,10 @@ import tech.beshu.ror.es.utils.RestToXContentWithStatusListener class RestRRAdminAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("POST", constants.FORCE_RELOAD_CONFIG_PATH) - register("GET", constants.PROVIDE_INDEX_CONFIG_PATH) - register("POST", constants.UPDATE_INDEX_CONFIG_PATH) - register("GET", constants.PROVIDE_FILE_CONFIG_PATH) + register("POST", constants.FORCE_RELOAD_SETTINGS_PATH) + register("GET", constants.PROVIDE_INDEX_SETTINGS_PATH) + register("POST", constants.UPDATE_INDEX_SETTINGS_PATH) + register("GET", constants.PROVIDE_FILE_SETTINGS_PATH) override val getName: String = "ror-admin-handler" diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 042bd0cf4d..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private NodeConfig nodeConfig; - - public RRConfig() { - super(); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index e59b752080..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = RRConfigsResponseReader -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala deleted file mode 100644 index 03e7017e59..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigReader extends Writeable.Reader[RRConfig] { - override def read(in: StreamInput): RRConfig = { - val response = new RRConfig - response.readFrom(in) - response - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index f862d0257a..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest() { - super(); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0da3e50dd5..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private NodeConfigRequest nodeConfigRequest; - - public RRConfigsRequest() { - super(); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 812d77e4ca..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse() { - super(); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfigReader::read); - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } - -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala deleted file mode 100644 index 226e15cefe..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponseReader.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} - -object RRConfigsResponseReader extends Writeable.Reader[RRConfigsResponse] { - override def read(in: StreamInput): RRConfigsResponse = { - val response = new RRConfigsResponse - response.readNodesFrom(in) - response - } -} \ No newline at end of file diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 60c2f10965..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - () => new RRConfigsRequest(), - () => new RRConfigRequest(), - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(): RRConfig = - new RRConfig() - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index e391a67490..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.settings.Settings -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(settings: Settings, - controller: RestController, - nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler(settings) { - - register("GET", constants.MANAGE_ROR_CONFIG_PATH) - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - - private def register(method: String, path: String): Unit = - controller.registerHandler(RestRequest.Method.valueOf(method), path, this) -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index 095a027ee9..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def this() = { - this(null, null) - } - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 47733a387e..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, () => new RRTestConfigRequest() - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 4fcf252c1f..ccdf13ac89 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject @@ -22,25 +22,25 @@ import org.elasticsearch.common.settings.Settings import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @Inject -class RestRRTestConfigAction(settings: Settings, controller: RestController) +class RestRRTestSettingsAction(settings: Settings, controller: RestController) extends BaseRestHandler(settings) with RestHandler { - register("GET", constants.PROVIDE_TEST_CONFIG_PATH) - register("POST", constants.UPDATE_TEST_CONFIG_PATH) - register("DELETE", constants.DELETE_TEST_CONFIG_PATH) + register("GET", constants.PROVIDE_TEST_SETTINGS_PATH) + register("POST", constants.UPDATE_TEST_SETTINGS_PATH) + register("DELETE", constants.DELETE_TEST_SETTINGS_PATH) register("GET", constants.PROVIDE_LOCAL_USERS_PATH) override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index 57fcf6f6c1..0bdf0ce63d 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es73x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d3b8accded..942c9d37cd 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,12 +35,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - fipsCompliant: Boolean) + ssl: ExternalSslSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es73x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es73x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index cd75902e1b..b791d55d2d 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -213,7 +214,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 3a85c2cb3b..7962bb140e 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,16 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) xContentRegistry: NamedXContentRegistry, networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl) } - ) + } .toMap .asJava } @@ -186,16 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -208,8 +202,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +222,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(restController), new RestRRAuthMockAction(restController), - new RestRRTestConfigAction(restController), - new RestRRConfigAction(restController, nodesInCluster), + new RestRRTestSettingsAction(restController), new RestRRUserMetadataAction(restController), new RestRRAuditEventAction(restController) ).asJava diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 89433a61d9..6cba50142b 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -28,10 +28,10 @@ import tech.beshu.ror.es.utils.RestToXContentWithStatusListener class RestRRAdminAction(controller: RestController) extends BaseRestHandler with RestHandler { - register("POST", constants.FORCE_RELOAD_CONFIG_PATH) - register("GET", constants.PROVIDE_INDEX_CONFIG_PATH) - register("POST", constants.UPDATE_INDEX_CONFIG_PATH) - register("GET", constants.PROVIDE_FILE_CONFIG_PATH) + register("POST", constants.FORCE_RELOAD_SETTINGS_PATH) + register("GET", constants.PROVIDE_FILE_SETTINGS_PATH) + register("GET", constants.PROVIDE_INDEX_SETTINGS_PATH) + register("POST", constants.UPDATE_INDEX_SETTINGS_PATH) override val getName: String = "ror-admin-handler" @@ -46,4 +46,4 @@ class RestRRAdminAction(controller: RestController) private def register(method: String, path: String): Unit = { controller.registerHandler(RestRequest.Method.valueOf(method), path, this) } -} \ No newline at end of file +} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index ef51710fdf..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.{EsEnv, IndexJsonContentService} -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index c13bccc030..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(controller: RestController, - nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - register("GET", constants.MANAGE_ROR_CONFIG_PATH) - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - - private def register(method: String, path: String): Unit = - controller.registerHandler(RestRequest.Method.valueOf(method), path, this) -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 70% rename from es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 9bf45abb4e..664214265b 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,32 +14,32 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.node.NodeClient import org.elasticsearch.common.inject.Inject import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener @Inject -class RestRRTestConfigAction(controller: RestController) +class RestRRTestSettingsAction(controller: RestController) extends BaseRestHandler with RestHandler { - register("GET", constants.PROVIDE_TEST_CONFIG_PATH) - register("POST", constants.UPDATE_TEST_CONFIG_PATH) - register("DELETE", constants.DELETE_TEST_CONFIG_PATH) + register("GET", constants.PROVIDE_TEST_SETTINGS_PATH) + register("POST", constants.UPDATE_TEST_SETTINGS_PATH) + register("DELETE", constants.DELETE_TEST_SETTINGS_PATH) register("GET", constants.PROVIDE_LOCAL_USERS_PATH) override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } diff --git a/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index 57fcf6f6c1..0bdf0ce63d 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es74x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d3b8accded..942c9d37cd 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,12 +35,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - fipsCompliant: Boolean) + ssl: ExternalSslSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es74x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es74x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c1bc4daed4..00752386cc 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.snapshots.SnapshotsService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], snapshotsServiceSupplier: Supplier[Option[SnapshotsService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -212,7 +213,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index d2c65624d0..d68bd2be24 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService import org.elasticsearch.threadpool.ThreadPool @@ -49,25 +50,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,15 +100,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -129,7 +129,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, SnapshotsServiceInterceptor.snapshotsServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -168,16 +168,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings) } - ) + } .toMap .asJava } @@ -188,16 +185,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -210,8 +204,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -231,8 +224,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 4720e2a6cf..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 74c96fdf67..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..26e9e92cb0 --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index 57fcf6f6c1..0bdf0ce63d 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetaData], + def filter(templates: Iterable[IndexTemplateMetaData], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetaData] = { val templatesMap = templates diff --git a/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es77x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 48c7e34c54..6b54f75c23 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,13 +35,12 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - clusterSettings: ClusterSettings, - fipsCompliant: Boolean) + ssl: ExternalSslSettings, + clusterSettings: ClusterSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es77x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es77x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 9174554860..015f4f4905 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -27,6 +27,7 @@ import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, IndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -34,12 +35,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo} import tech.beshu.ror.implicits.* @@ -58,20 +59,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -212,7 +213,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index cabc889b9c..0c4dcdac1a 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.MapperService import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,25 +51,24 @@ import org.elasticsearch.transport.netty4.Netty4Utils import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -101,15 +101,15 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -131,7 +131,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -170,16 +170,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings) } - ) + } .toMap .asJava } @@ -190,16 +187,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl) } - ) + } .toMap .asJava } @@ -212,8 +206,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -233,8 +226,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 4720e2a6cf..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 74c96fdf67..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..26e9e92cb0 --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index aa52fe4beb..c170a8c87d 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetadata], + def filter(templates: Iterable[IndexTemplateMetadata], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetadata] = { val templatesMap = templates diff --git a/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es78x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 48c7e34c54..6b54f75c23 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,13 +35,12 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, - clusterSettings: ClusterSettings, - fipsCompliant: Boolean) + ssl: ExternalSslSettings, + clusterSettings: ClusterSettings) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 385e17147e..470f7f2a18 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,13 +42,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - fipsCompliant: Boolean) + ssl: InternodeSslSettings) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -65,7 +65,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es78x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es78x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 0e96c82c0e..1c63128a26 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index a490c0fa98..b92a933cfa 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -39,8 +40,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,26 +51,25 @@ import org.elasticsearch.transport.{SharedGroupFactory, Transport, TransportInte import org.elasticsearch.watcher.ResourceWatcherService import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) TransportServiceInterceptor.remoteClusterServiceSupplier, RepositoriesServiceInterceptor.repositoriesServiceSupplier, esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,16 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = doPrivileged { - new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -193,16 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = doPrivileged { - new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) - } + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -220,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -241,8 +234,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 950e053439..8eaaf10e73 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,33 +20,33 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -57,10 +57,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index caeafd8a99..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 25c8d6113b..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeRequest; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends BaseNodeRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 708e6d6176..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - override def newNodeResponse(in: StreamInput): RRConfig = - new RRConfig(in) - - override def nodeOperation(request: RRConfigRequest): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = loadConfig().runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 4720e2a6cf..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.unit.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 8f44e4149c..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.common.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 68c81790f3..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} -import org.elasticsearch.rest.RestStatus -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 74c96fdf67..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..16e8851da7 --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,129 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.{StatusToXContentObject, ToXContent, XContentBuilder} +import org.elasticsearch.rest.RestStatus +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..26e9e92cb0 --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala b/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala index aa52fe4beb..c170a8c87d 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetTemplatesEsRequestContext.scala @@ -102,7 +102,7 @@ class GetTemplatesEsRequestContext(actionRequest: GetIndexTemplatesRequest, private[templates] object GetTemplatesEsRequestContext extends Logging { - def filter(templates: List[IndexTemplateMetadata], + def filter(templates: Iterable[IndexTemplateMetadata], usingTemplate: Set[Template] => Set[Template]) (implicit requestContextId: RequestContext.Id): List[IndexTemplateMetadata] = { val templatesMap = templates diff --git a/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..e7f5ac4866 --- /dev/null +++ b/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.common.xcontent.XContentType +import org.elasticsearch.index.IndexNotFoundException +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 18490a232c..0000000000 --- a/es79x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.common.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 3fb7bb8b1b..d30183cb08 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 18bb5fb961..2d49fb875f 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -67,7 +67,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es79x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es79x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index aa1fc13e4e..d3f1c12ba2 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4811436e3d..de707dbc39 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -37,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -49,27 +50,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,14 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -184,14 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -209,8 +207,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -231,8 +228,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index fca63703b9..11c1034928 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 34aad32d86..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index ac1ad056c8..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 74c96fdf67..0000000000 --- a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3426623ea9..e15d4f329a 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -58,10 +58,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..26e9e92cb0 --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.rest.* +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es80x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es80x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..71f6ba880d --- /dev/null +++ b/es80x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f69eef25d2..675646d3ee 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es80x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es80x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 610a687a06..992492c525 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -52,27 +53,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -107,16 +107,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -142,7 +142,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -176,14 +176,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -194,14 +193,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -219,8 +217,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -241,8 +238,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index d6f4699d23..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index 3426623ea9..e15d4f329a 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -58,10 +58,10 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index c2da8cabe9..500846af8d 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer @@ -22,29 +22,29 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es810x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es810x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 5e693123f3..26296f7491 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7438934b6f..36250d24e7 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es810x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es810x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index ca4cbdac21..98978457ef 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -53,27 +54,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -108,16 +108,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -143,7 +143,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -177,14 +177,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -195,14 +194,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -220,8 +218,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -242,8 +239,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index c30df9b180..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 5bd6a7e3e6..49fb686fe1 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 526b1f9237..500846af8d 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 5e693123f3..26296f7491 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es811x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b1b9f30bd0..7fc953e792 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es811x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es811x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 73ea801d70..1a98de367a 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -45,27 +46,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -100,16 +100,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -124,7 +124,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -158,14 +158,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -176,14 +175,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -201,8 +199,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -223,8 +220,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 35e57bce86..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 5bd6a7e3e6..49fb686fe1 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 526b1f9237..500846af8d 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala b/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala index 58eadf39ec..22869bbb4f 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala @@ -22,7 +22,6 @@ import org.elasticsearch.threadpool.ThreadPool import org.joor.Reflect.on import tech.beshu.ror.accesscontrol.blocks.BlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.SnapshotRequestBlockContext -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.{ClusterIndexName, RepositoryName, RequestedIndex, SnapshotName} import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.es.RorClusterService diff --git a/es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 70% rename from es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 2e75d37d0f..26296f7491 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,27 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -45,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -60,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -93,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -115,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es812x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b1b9f30bd0..7fc953e792 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es812x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es812x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 2db1d8e565..f79b6ee525 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -46,27 +47,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -101,16 +101,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -125,7 +125,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -159,14 +159,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -177,14 +176,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -202,8 +200,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -226,8 +223,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 35e57bce86..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 5bd6a7e3e6..49fb686fe1 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index 526b1f9237..500846af8d 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -@Inject -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es813x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala b/es813x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala index 58eadf39ec..22869bbb4f 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala @@ -22,7 +22,6 @@ import org.elasticsearch.threadpool.ThreadPool import org.joor.Reflect.on import tech.beshu.ror.accesscontrol.blocks.BlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.SnapshotRequestBlockContext -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.{ClusterIndexName, RepositoryName, RequestedIndex, SnapshotName} import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.es.RorClusterService diff --git a/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es813x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b1b9f30bd0..7fc953e792 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es813x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es813x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 2db1d8e565..f79b6ee525 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -46,27 +47,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -101,16 +101,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -125,7 +125,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -159,14 +159,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -177,14 +176,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -202,8 +200,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -226,8 +223,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 35e57bce86..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 5bd6a7e3e6..49fb686fe1 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es814x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es814x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala b/es814x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala index 58eadf39ec..22869bbb4f 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/snapshots/GetSnapshotsEsRequestContext.scala @@ -22,7 +22,6 @@ import org.elasticsearch.threadpool.ThreadPool import org.joor.Reflect.on import tech.beshu.ror.accesscontrol.blocks.BlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.SnapshotRequestBlockContext -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.{ClusterIndexName, RepositoryName, RequestedIndex, SnapshotName} import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.es.RorClusterService diff --git a/es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es814x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b1b9f30bd0..7fc953e792 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es814x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es814x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 53fd0c18f4..fb007c80e1 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -47,27 +48,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(client), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -162,14 +162,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -180,14 +179,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -205,8 +203,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +226,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 6c83268805..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 4552b6e325..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest -import tech.beshu.ror.es.utils.EsEnvProvider - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 7ac7d78766..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index d2c63676b7..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import tech.beshu.ror.es.utils.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 5bd6a7e3e6..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService - -import java.util.concurrent.Executor -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters, - threadPool: ThreadPool) = - this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..ad72c8e5cf --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import tech.beshu.ror.es.utils.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..49fb686fe1 --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,48 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.threadpool.ThreadPool +import org.elasticsearch.transport.TransportService + +import java.util.concurrent.Executor +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters, + threadPool: ThreadPool) = + this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es815x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetComponentTemplateEsRequestContext.scala b/es815x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetComponentTemplateEsRequestContext.scala index d0235fd407..a12ab32d6e 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetComponentTemplateEsRequestContext.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/templates/GetComponentTemplateEsRequestContext.scala @@ -91,7 +91,7 @@ class GetComponentTemplateEsRequestContext(actionRequest: GetComponentTemplateAc new GetComponentTemplateAction.Response( filter( templates = r.getComponentTemplates.asSafeMap, - usingTemplate = using.responseTemplateTransformation + usingTemplate = `using`.responseTemplateTransformation ), r.getRolloverConfiguration, r.getGlobalRetention diff --git a/es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es815x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b1b9f30bd0..7fc953e792 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es815x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es815x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b19dd45353..ed16bfcc14 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -47,27 +48,26 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -128,7 +128,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(client), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -162,14 +162,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -180,14 +179,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -205,8 +203,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -229,8 +226,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 1ecc29436c..7770420170 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -32,10 +32,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 9e8b4485a2..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.injection.guice.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 6a9c7e16d3..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 31a5826de5..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig, Void]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 2892f898f9..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.rest.* -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import java.util -import java.util.function.Supplier -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index d2c63676b7..0000000000 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import tech.beshu.ror.es.utils.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..ad72c8e5cf --- /dev/null +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import tech.beshu.ror.es.utils.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 2d936937d3..d72dc8acfe 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es816x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 40ae6d97e0..c1c6c8a26b 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 0ff995d0f2..33abeef01f 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,7 +28,7 @@ import org.elasticsearch.telemetry.tracing.Tracer import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,15 +36,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es816x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es816x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 0e49cccf98..ed16bfcc14 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,6 @@ import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction @@ -167,7 +166,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.externalSsl) .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } } .toMap @@ -184,7 +183,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.internodeSsl) .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } } .toMap diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 38403cff0c..33abeef01f 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -39,12 +39,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index c42eb32d37..58d76ddebb 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -43,13 +44,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, ssl: InternodeSslSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c3240ac12b..acfef36a08 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b66148d79b..debb9f2bd2 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -37,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -49,27 +50,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,14 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -184,14 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -209,8 +207,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -231,8 +228,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 53a610f3dd..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es81x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es81x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es81x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f69eef25d2..675646d3ee 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es81x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es81x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c3240ac12b..acfef36a08 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index b66148d79b..debb9f2bd2 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -37,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -49,27 +50,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,14 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -184,14 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -209,8 +207,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -231,8 +228,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 53a610f3dd..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es82x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es82x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es82x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f69eef25d2..675646d3ee 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -36,14 +36,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es82x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es82x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c3240ac12b..acfef36a08 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 43da8aed30..99e306fd7e 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -37,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -49,27 +50,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -102,16 +102,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -134,7 +134,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -166,14 +166,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) networkService: NetworkService, dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -184,14 +183,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -209,8 +207,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -231,8 +228,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 53a610f3dd..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import java.util -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 7d5bdddcf7..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{BytesRestResponse, RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new BytesRestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es83x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es83x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es83x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 9d0b2a1a48..ce726c249b 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -26,7 +26,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -34,14 +34,13 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es83x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es83x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index c3240ac12b..acfef36a08 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -224,7 +225,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index d52c8b6cc1..ed59594e9e 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -37,8 +38,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -50,27 +51,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -103,16 +103,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -136,7 +136,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -169,14 +169,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -187,14 +186,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -212,8 +210,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -234,8 +231,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 894e1017c3..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.configuration.EnvironmentConfig -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es84x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es84x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es84x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index aa076ad5a2..f1afbea188 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es84x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es84x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 6ed2d541bc..6c24256a1c 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -38,8 +39,8 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.script.ScriptService @@ -51,27 +52,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -106,16 +106,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -140,7 +140,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -238,8 +235,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 9a279e99eb..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es85x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es85x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es85x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index aa076ad5a2..f1afbea188 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 84a0ca989a..16a31fa908 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -28,7 +28,8 @@ import org.elasticsearch.common.util.PageCacheRecycler import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -41,14 +42,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { @@ -66,7 +66,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es85x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es85x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 4f029b4ac4..898a72b80b 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -51,27 +52,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -106,16 +106,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -140,7 +140,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -173,14 +173,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) dispatcher: HttpServerTransport.Dispatcher, clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -191,14 +190,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -216,8 +214,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -238,8 +235,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 9a279e99eb..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es87x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es87x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es87x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 300fa59dd9..b80f3b9150 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index bace72fc19..cbbed3e208 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es87x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es87x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8914d670e3..fb7daa1a3f 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -51,27 +52,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -106,16 +106,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -140,7 +140,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -174,14 +174,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -192,14 +191,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -217,8 +215,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -239,8 +236,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 9a279e99eb..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es88x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es88x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es88x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index fcc712761c..4992b28bfd 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index bace72fc19..cbbed3e208 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es88x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es88x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 63a0c6d52e..a369e8f646 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) (implicit systemContext: SystemContext) extends ActionFilter with Logging { private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -223,7 +224,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 8914d670e3..fb7daa1a3f 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -51,27 +52,26 @@ import org.elasticsearch.watcher.ResourceWatcherService import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.settings.es.ReadonlyRestEsConfig -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.actions.wrappers._upgrade.{RorWrappedUpgradeActionType, TransportRorWrappedUpgradeAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -106,16 +106,16 @@ class ReadonlyRestPlugin(s: Settings, p: Path) private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(client: Client, clusterService: ClusterService, @@ -140,7 +140,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(repositoriesServiceSupplier), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -174,14 +174,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, tracer: Tracer): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } - ) + } .toMap .asJava } @@ -192,14 +191,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -217,8 +215,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler[_ <: ActionRequest, _ <: ActionResponse]]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -239,8 +236,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index ab68db4ca4..16997c0c09 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -26,7 +26,7 @@ class RRAdminActionType extends ActionType[RRAdminResponse]( ) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 7d647dbbe7..4562b46edc 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -21,33 +21,33 @@ import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.common.xcontent.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status(): RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 030523983f..7183148074 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -34,10 +34,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 4c54fc5429..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfig; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 68e18996bc..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name, RRConfigActionType.reader) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 91db914374..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.transport.TransportRequest; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; - -public class RRConfigRequest extends TransportRequest { - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - super(); - this.nodeConfigRequest = nodeConfigRequest; - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 3e49f6908a..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.settings.es.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.settings.es.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - private final NodeConfigRequest nodeConfigRequest; - - @Inject - public RRConfigsRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public RRConfigsRequest(NodeConfigRequest nodeConfigRequest, DiscoveryNode... concreteNodes) { - super(concreteNodes); - this.nodeConfigRequest = nodeConfigRequest; - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigRequestSerializer.serialize(this.nodeConfigRequest)); - } - - @Override - public String toString() { - return "RRConfigsRequest{" + - "concreteNodes=" + Arrays.asList(concreteNodes()) + - '}'; - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 82c715a4b4..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeList(nodes); - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index 9a279e99eb..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.SystemContext -import tech.beshu.ror.settings.es.loader.* -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfig, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - request: Writeable.Reader[RRConfigsRequest], - nodeRequest: Writeable.Reader[RRConfigRequest], - nodeExecutor: String, - nodeResponseClass: Class[RRConfig], - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig]( - actionName, - threadPool, - clusterService, - transportService, - actionFilters, - request, - nodeRequest, - nodeExecutor, - nodeResponseClass - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val systemContext: SystemContext = SystemContext.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - threadPool, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigsRequest(_), - new RRConfigRequest(_), - ThreadPool.Names.GENERIC, - classOf[RRConfig], - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(request.getNodeConfigRequest) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 3530227ea7..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util -import java.util.function.Supplier - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.core.TimeValue -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.settings.es.loader.distributed.{NodeConfigRequest, Timeout} -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - val timeout = getTimeout(request, RestRRConfigAction.defaultTimeout) - val requestConfig = NodeConfigRequest( - timeout = Timeout(timeout.nanos()) - ) - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(requestConfig, nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def getTimeout(request: RestRequest, default: TimeValue) = - request.paramAsTime("timeout", default) - - private def nodes = - nodesInCluster.get().asScala.toList - -} -object RestRRConfigAction { - private val defaultTimeout: TimeValue = toTimeValue(NodeConfigRequest.defaultTimeout) - private def toTimeValue(timeout: Timeout):TimeValue = TimeValue.timeValueNanos(timeout.nanos) -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 9bd3910dcf..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse -import tech.beshu.ror.settings.es.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala deleted file mode 100644 index aa8bb31e67..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import cats.implicits.toShow -import monix.execution.Scheduler -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.action.ActionListener -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged -import tech.beshu.ror.utils.RorInstanceSupplier - -class RRTestConfigActionHandler extends Logging { - - private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - getApi match { - case Some(api) => doPrivileged { - implicit val requestId: RequestId = request.requestContextId - api - .call(request.getTestConfigRequest) - .runAsync { result => - handle(result, listener) - } - } - case None => - listener.onFailure(new Exception("TestConfig API is not available")) - } - } - - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) - (implicit requestId: RequestId): Unit = result match { - case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) - case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) - listener.onFailure(new Exception(ex)) - } - - private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala deleted file mode 100644 index b0487bce17..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRTestConfigActionType extends ActionType[RRTestConfigResponse]( - RRTestConfigActionType.name, RRTestConfigActionType.exceptionReader -) - -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() - - case object RRTestConfigActionCannotBeTransported extends Exception - - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported -} - diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala deleted file mode 100644 index d4574bf654..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} -import org.elasticsearch.rest.RestRequest -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.RorActionRequest -import tech.beshu.ror.utils.ScalaOps.* - -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) - - lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") - - override def validate(): ActionRequestValidationException = null -} - -object RRTestConfigRequest { - - def createFrom(request: RestRequest): RRTestConfigRequest = { - val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig - case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers - case (unknownUri, unknownMethod) => - throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") - } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), - request - ) - } -} - diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala deleted file mode 100644 index 3426623ea9..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionResponse -import org.elasticsearch.common.io.stream.StreamOutput -import org.elasticsearch.common.xcontent.StatusToXContentObject -import org.elasticsearch.rest.RestStatus -import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* - -import java.time.ZoneOffset - -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) - extends ActionResponse with StatusToXContentObject { - - override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { - response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) - } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) - } - case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { - case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) - case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) - } - case failure: Failure => failure match { - case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) - } - } - builder - } - - override def writeTo(out: StreamOutput): Unit = () - - override def status(): RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK - case _: ProvideLocalUsers => RestStatus.OK - case failure: Failure => failure match { - case Failure.BadRequest(_) => RestStatus.BAD_REQUEST - } - } - - private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { - builder.startObject - builder.field("status", status) - builder.field("message", message) - builder.endObject - } - - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("settings", response.settings.raw) - builder.field("ttl", response.ttl.toString()) - builder.endObject - } - - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.field("message", response.message) - builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) - warningsJson(builder, response.warnings) - builder.endObject - } - - private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { - builder.startObject - builder.field("status", response.status) - builder.startArray("users") - response.users.foreach { user => - builder.value(user) - } - builder.endArray() - builder.field("unknown_users", response.unknownUsers) - builder.endObject - } - - private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { - builder.startArray("warnings") - warnings.foreach { warning => - builder.startObject() - builder.field("block_name", warning.blockName) - builder.field("rule_name", warning.ruleName) - builder.field("message", warning.message) - builder.field("hint", warning.hint) - builder.endObject() - } - builder.endArray() - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala deleted file mode 100644 index 688fd79e44..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig - -import org.elasticsearch.action.ActionListener -import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.transport.TransportService - -import scala.annotation.unused - -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader - ) { - - @Inject - def this(transportService: TransportService, - actionFilters: ActionFilters) = - this(transportService, actionFilters, ()) - - private val handler = new RRTestConfigActionHandler() - - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { - handler.handle(request, listener) - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala deleted file mode 100644 index 526b1f9237..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrtestconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.Inject -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} -import org.elasticsearch.rest.* -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} -import tech.beshu.ror.es.utils.RestToXContentWithStatusListener - -import java.util -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRTestConfigAction - extends BaseRestHandler with RestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), - new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) - ).asJava - - override val getName: String = "ror-test-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) - - override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) - } - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala new file mode 100644 index 0000000000..3fe2540c1b --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -0,0 +1,61 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import cats.implicits.toShow +import monix.execution.Scheduler +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.action.ActionListener +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.implicits.* +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged +import tech.beshu.ror.utils.RorInstanceSupplier + +class RRTestSettingsActionHandler extends Logging { + + private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler + + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + getApi match { + case Some(api) => doPrivileged { + implicit val requestId: RequestId = request.requestContextId + api + .call(request.getTestSettingsRequest) + .runAsync { result => + handle(result, listener) + } + } + case None => + listener.onFailure(new Exception("ROR Test Settings API is not available")) + } + } + + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) + (implicit requestId: RequestId): Unit = result match { + case Right(response) => + listener.onResponse(new RRTestSettingsResponse(response)) + case Left(ex) => + logger.error(s"[${requestId.show}] Internal error", ex) + listener.onFailure(new Exception(ex)) + } + + private def getApi = + RorInstanceSupplier.get().map(_.testSettingsApi) +} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala new file mode 100644 index 0000000000..acb9636010 --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -0,0 +1,35 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionType +import org.elasticsearch.common.io.stream.Writeable +import tech.beshu.ror.accesscontrol.domain.Action.RorAction + +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse]( + RRTestSettingsActionType.name, + RRTestSettingsActionType.exceptionReader +) + +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() + + case object RRAdminActionCannotBeTransported extends Exception + + def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRAdminActionCannotBeTransported +} \ No newline at end of file diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala new file mode 100644 index 0000000000..c690c5ecfd --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -0,0 +1,60 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} +import org.elasticsearch.rest.RestRequest +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.RorActionRequest +import tech.beshu.ror.utils.ScalaOps.* + +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { + + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) + + lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") + + override def validate(): ActionRequestValidationException = null +} + +object RRTestSettingsRequest { + + def createFrom(request: RestRequest): RRTestSettingsRequest = { + val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings + case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers + case (unknownUri, unknownMethod) => + throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") + } + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), + request + ) + } +} + diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala new file mode 100644 index 0000000000..e15d4f329a --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -0,0 +1,130 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionResponse +import org.elasticsearch.common.io.stream.StreamOutput +import org.elasticsearch.common.xcontent.StatusToXContentObject +import org.elasticsearch.rest.RestStatus +import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* + +import java.time.ZoneOffset + +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) + extends ActionResponse with StatusToXContentObject { + + override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { + response match { + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) + } + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) + } + case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { + case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) + case ProvideLocalUsers.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case ProvideLocalUsers.TestSettingsInvalidated(message) => addResponseJson(builder, response.status, message) + } + case failure: Failure => failure match { + case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) + } + } + builder + } + + override def writeTo(out: StreamOutput): Unit = () + + override def status: RestStatus = response match { + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK + case _: ProvideLocalUsers => RestStatus.OK + case failure: Failure => failure match { + case Failure.BadRequest(_) => RestStatus.BAD_REQUEST + } + } + + private def addResponseJson(builder: XContentBuilder, status: String, message: String): Unit = { + builder.startObject + builder.field("status", status) + builder.field("message", message) + builder.endObject + } + + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("ttl", response.ttl.toString()) + builder.field("settings", response.settings.rawYaml) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("settings", response.settings.rawYaml) + builder.field("ttl", response.ttl.toString()) + builder.endObject + } + + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.field("message", response.message) + builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) + warningsJson(builder, response.warnings) + builder.endObject + } + + private def provideLocalUsersJson(builder: XContentBuilder, response: ProvideLocalUsers.SuccessResponse): Unit = { + builder.startObject + builder.field("status", response.status) + builder.startArray("users") + response.users.foreach { user => + builder.value(user) + } + builder.endArray() + builder.field("unknown_users", response.unknownUsers) + builder.endObject + } + + private def warningsJson(builder: XContentBuilder, warnings: List[Warning]): Unit = { + builder.startArray("warnings") + warnings.foreach { warning => + builder.startObject() + builder.field("block_name", warning.blockName) + builder.field("rule_name", warning.ruleName) + builder.field("message", warning.message) + builder.field("hint", warning.hint) + builder.endObject() + } + builder.endArray() + } +} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala new file mode 100644 index 0000000000..35e40b8f73 --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -0,0 +1,45 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings + +import org.elasticsearch.action.ActionListener +import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.tasks.Task +import org.elasticsearch.transport.TransportService + +import scala.annotation.unused + +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader + ) { + + @Inject + def this(transportService: TransportService, + actionFilters: ActionFilters) = { + this(transportService, actionFilters, ()) + } + + private val handler = new RRTestSettingsActionHandler() + + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { + handler.handle(request, listener) + } +} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala new file mode 100644 index 0000000000..500846af8d --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -0,0 +1,50 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.actions.rrtestsettings.rest + +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer +import org.elasticsearch.rest.RestHandler.Route +import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} +import org.elasticsearch.rest.* +import tech.beshu.ror.constants +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} +import tech.beshu.ror.es.utils.RestToXContentWithStatusListener + +import java.util +import scala.jdk.CollectionConverters.* + +class RestRRTestSettingsAction + extends BaseRestHandler with RestHandler { + + override def routes(): util.List[Route] = List( + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) + ).asJava + + override val getName: String = "ror-test-config-handler" + + override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) + + override def accept(channel: RestChannel): Unit = { + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) + } + } +} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index ad66bd8f35..9c00906853 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.settings.es.RorBootConfiguration -import tech.beshu.ror.settings.es.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es89x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala b/es89x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala index 584c97e9f5..05b70606b9 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/MultiGetEsRequestContext.scala @@ -26,7 +26,6 @@ import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.accesscontrol.blocks.BlockContext.FilterableMultiRequestBlockContext import tech.beshu.ror.accesscontrol.blocks.BlockContext.MultiIndexRequestBlockContext.Indices import tech.beshu.ror.accesscontrol.blocks.metadata.UserMetadata -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.* import tech.beshu.ror.accesscontrol.domain.DocumentAccessibility.{Accessible, Inaccessible} import tech.beshu.ror.accesscontrol.domain.FieldLevelSecurity.RequestFieldsUsage diff --git a/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala new file mode 100644 index 0000000000..26296f7491 --- /dev/null +++ b/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -0,0 +1,118 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.es.services + +import cats.implicits.* +import io.circe.Json +import io.circe.parser.* +import monix.eval.Task +import org.apache.logging.log4j.scala.Logging +import org.elasticsearch.ResourceNotFoundException +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy +import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.common.inject.Inject +import org.elasticsearch.index.IndexNotFoundException +import org.elasticsearch.xcontent.XContentType +import tech.beshu.ror.accesscontrol.domain.IndexName +import tech.beshu.ror.boot.RorSchedulers +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* +import tech.beshu.ror.implicits.* + +import scala.annotation.unused + +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager + with Logging { + + @Inject + def this(client: NodeClient) = { + this(client, ()) + } + + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { + Task { + client + .get( + client + .prepareGet() + .setIndex(index.name.value) + .setId(id) + .request() + ) + .actionGet() + } + .map { response => + if (response.isExists) { + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } + case None => + logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") + Right(Json.Null) + } + } else { + logger.debug(s"Document [${index.show} ID=$id] not exist") + Left(DocumentNotFound) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) + case ex => + logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) + Left(DocumentUnreachable) + } + } + + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { + Task { + client + .index( + client + .prepareIndex() + .setIndex(index.name.value) + .setId(id) + .setSource(document.noSpaces, XContentType.JSON) + .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) + .request() + ) + .actionGet() + } + .map { response => + response.status().getStatus match { + case status if status / 100 == 2 => + Right(()) + case status => + logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") + Left(CannotWriteToIndex) + } + } + .executeOn(RorSchedulers.blockingScheduler) + .onErrorRecover { + case ex => + logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) + Left(CannotWriteToIndex) + } + } +} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala deleted file mode 100644 index 2e75d37d0f..0000000000 --- a/es89x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.services - -import cats.implicits.* -import monix.eval.Task -import org.apache.logging.log4j.scala.Logging -import org.elasticsearch.ResourceNotFoundException -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.common.inject.{Inject, Singleton} -import org.elasticsearch.xcontent.XContentType -import tech.beshu.ror.accesscontrol.domain.IndexName -import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* -import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* - -import scala.annotation.unused -import scala.jdk.CollectionConverters.* - -@Singleton -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService - with Logging { - - @Inject - def this(client: NodeClient) = { - this(client, ()) - } - - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { - Task { - client - .get( - client - .prepareGet() - .setIndex(index.name.value) - .setId(id) - .request() - ) - .actionGet() - } - .map { response => - if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) - case None => - logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) - } - } else { - logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) - case ex => - logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) - } - } - - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { - Task { - client - .index( - client - .prepareIndex() - .setIndex(index.name.value) - .setId(id) - .setSource(content.asJava, XContentType.JSON) - .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) - .request() - ) - .actionGet() - } - .map { response => - response.status().getStatus match { - case status if status / 100 == 2 => - Right(()) - case status => - logger.error(s"Cannot write to document [${index.show} ID=$id]. Unexpected response: HTTP $status, response: ${response.toString}") - Left(CannotWriteToIndex) - } - } - .executeOn(RorSchedulers.blockingScheduler) - .onErrorRecover { - case ex => - logger.error(s"Cannot write to document [${index.show} ID=$id]", ex) - Left(CannotWriteToIndex) - } - } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } -} diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7438934b6f..36250d24e7 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.settings.es.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 3728ca317d..58d76ddebb 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.settings.es.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es89x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es89x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index f01429df0c..406c2de9e7 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configFile(), - modulesPath = environment.modulesFile(), + configDir = File(environment.configFile()), + modulesDir = File(environment.configFile()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 121ea147d2..638806dbbd 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -49,7 +49,6 @@ import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction @@ -166,7 +165,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.externalSsl) .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } } .toMap @@ -183,7 +182,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.internodeSsl) .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } } .toMap diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 38403cff0c..33abeef01f 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -39,12 +39,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index c42eb32d37..58d76ddebb 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -43,13 +44,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, ssl: InternodeSslSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 22c06602ed..f20f432a23 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -35,8 +36,8 @@ import org.elasticsearch.http.{HttpPreRequest, HttpServerTransport} import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.telemetry.tracing.Tracer @@ -47,7 +48,6 @@ import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction @@ -164,7 +164,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.externalSsl) .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer, ssl.fipsMode.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), tracer) } } .toMap @@ -181,7 +181,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) .ssl.flatMap(_.internodeSsl) .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), ssl.fipsMode.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } } .toMap diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 5b11452c83..7fc953e792 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -38,12 +38,11 @@ class SSLNetty4HttpServerTransport(settings: Settings, ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - tracer: Tracer, - fipsCompliant: Boolean) + tracer: Tracer) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index c42eb32d37..58d76ddebb 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -43,13 +44,12 @@ class SSLNetty4InternodeServerTransport(settings: Settings, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, ssl: InternodeSslSettings, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/settings.gradle b/settings.gradle index 30eb644da2..3078cf9ad0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,35 +29,35 @@ rootProject.name = 'readonlyrest' include 'ror-shadowed-libs' include 'audit' include 'core' -//include 'es67x' -//include 'es70x' -//include 'es72x' -//include 'es73x' -//include 'es74x' -//include 'es77x' -//include 'es78x' -//include 'es79x' -//include 'es710x' -//include 'es711x' -//include 'es714x' -//include 'es716x' -//include 'es717x' -//include 'es80x' -//include 'es81x' -//include 'es82x' -//include 'es83x' -//include 'es84x' -//include 'es85x' -//include 'es87x' -//include 'es88x' -//include 'es89x' -//include 'es810x' -//include 'es811x' -//include 'es812x' -//include 'es813x' -//include 'es814x' -//include 'es815x' -//include 'es816x' +include 'es67x' +include 'es70x' +include 'es72x' +include 'es73x' +include 'es74x' +include 'es77x' +include 'es78x' +include 'es79x' +include 'es710x' +include 'es711x' +include 'es714x' +include 'es716x' +include 'es717x' +include 'es80x' +include 'es81x' +include 'es82x' +include 'es83x' +include 'es84x' +include 'es85x' +include 'es87x' +include 'es88x' +include 'es89x' +include 'es810x' +include 'es811x' +include 'es812x' +include 'es813x' +include 'es814x' +include 'es815x' +include 'es816x' include 'es818x' include 'es90x' include 'es91x' From 5a56381e98bda9ab635eaaf61f9135cbecf80fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 2 Oct 2025 18:48:33 +0200 Subject: [PATCH 039/103] wip --- .../tech/beshu/ror/boot/RorInstance.scala | 1 - .../settings/ror/loader/RetryStrategy.scala | 26 +++++++++++-------- ...hFileSourceFallbackRorSettingsLoader.scala | 5 +++- .../ror/source/IndexSettingsSource.scala | 4 +-- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 4ae8fd9283..5ac26d223f 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -164,7 +164,6 @@ class RorInstance private(boot: ReadonlyRest, } } - // todo: check messages private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) (implicit requestId: RequestId): CancelableWithRequestId = { diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index 59aa8e5556..21a1975866 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -25,25 +25,30 @@ import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings trait RetryStrategy { - def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] - def withRetryT[ERROR: Show, RESULT](operation: EitherT[Task, ERROR, RESULT]): EitherT[Task, ERROR, RESULT] = - EitherT(withRetry(operation.value)) + def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], + operationDescription: String): Task[Either[ERROR, RESULT]] + def withRetryT[ERROR: Show, RESULT](operation: EitherT[Task, ERROR, RESULT], + operationDescription: String): EitherT[Task, ERROR, RESULT] = + EitherT(withRetry(operation.value, operationDescription)) } object NoRetryStrategy extends RetryStrategy { - override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] = + override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], + operationDescription: String): Task[Either[ERROR, RESULT]] = operation } class ConfigurableRetryStrategy(config: LoadingRetryStrategySettings) extends RetryStrategy with Logging { - override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]]): Task[Either[ERROR, RESULT]] = - attemptWithRetry(operation, currentAttempt = 1, config.attemptsCount.value.value) + override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], + operationDescription: String): Task[Either[ERROR, RESULT]] = + attemptWithRetry(operation, currentAttempt = 1, config.attemptsCount.value.value, operationDescription) private def attemptWithRetry[ERROR : Show, A](operation: Task[Either[ERROR, A]], currentAttempt: Int, - maxAttempts: Int): Task[Either[ERROR, A]] = { + maxAttempts: Int, + operationDescription: String): Task[Either[ERROR, A]] = { val delay = if (currentAttempt == 1) config.delay.value.value else config.attemptsInterval.value.value for { _ <- Task.sleep(delay) @@ -51,12 +56,11 @@ class ConfigurableRetryStrategy(config: LoadingRetryStrategySettings) finalResult <- result match { case Right(value) => Task.now(Right(value)) - // todo: better messages case Left(error) if shouldRetry(currentAttempt, maxAttempts) => - logger.debug(s"Retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${config.attemptsInterval.show}...") - attemptWithRetry(operation, currentAttempt + 1, maxAttempts) + logger.debug(s"$operationDescription - retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${config.attemptsInterval.show}...") + attemptWithRetry(operation, currentAttempt + 1, maxAttempts, operationDescription) case Left(error) => - logger.debug(s"Operation failed after $currentAttempt attempts: ${error.show}") + logger.debug(s"$operationDescription - failed after $currentAttempt attempts: ${error.show}") Task.now(Left(error)) } } yield finalResult diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala index efe762b09a..8426e9ed0d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader.scala @@ -31,7 +31,10 @@ class RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader(mainSettingsIn override def load(): Task[Either[LoadingError, (MainRorSettings, Option[TestRorSettings])]] = { val result = for { mainSettings <- mainSettingsIndexLoadingRetryStrategy - .withRetryT(loadMainSettingsFromIndex()) + .withRetryT( + operation = loadMainSettingsFromIndex(), + operationDescription = s"Loading ReadonlyREST main settings from index '${mainSettingsIndexSource.settingsIndex.show}'" + ) .orElse(loadMainSettingsFromFile()) testSettings <- loadTestSettingsFromIndex() .map(Option.apply) diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala index 4d0a8677df..0613fa8f68 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala @@ -44,10 +44,8 @@ class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: Ind } case Left(IndexDocumentManager.IndexNotFound) => settingsLoaderError(IndexNotFound) - case Left(IndexDocumentManager.DocumentNotFound) => + case Left(IndexDocumentManager.DocumentNotFound | IndexDocumentManager.DocumentUnreachable) => settingsLoaderError(DocumentNotFound) - case Left(IndexDocumentManager.DocumentUnreachable) => - settingsLoaderError(IndexNotFound) // todo: throw ex? } } From 0da6b00849e4ffcf0fd1b7bb740858c9705c68dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 8 Oct 2025 07:53:18 +0200 Subject: [PATCH 040/103] wip --- .../tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index 7c369b1417..42d1ab1944 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -40,6 +40,7 @@ import scala.language.{implicitConversions, postfixOps} final case class EsConfigBasedRorSettings(boot: RorBootSettings, ssl: Option[RorSslSettings], + // todo: rename - settings storeage related settingsIndex: RorSettingsIndex, settingsFile: RorSettingsFile, settingsMaxSize: Information, From 6b26b3377c5359b9ad2e639c4221327414eb2a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 8 Oct 2025 16:45:41 +0200 Subject: [PATCH 041/103] wi --- .../ror/accesscontrol/domain/indices.scala | 14 - .../ror/accesscontrol/domain/settings.scala | 38 +++ .../tech/beshu/ror/boot/ReadonlyRest.scala | 4 +- .../tech/beshu/ror/boot/RorInstance.scala | 4 +- .../SettingsRelatedCreatorsAndLoaders.scala | 20 +- .../boot/engines/BaseReloadableEngine.scala | 2 +- .../main/scala/tech/beshu/ror/es/EsEnv.scala | 6 +- .../main/scala/tech/beshu/ror/implicits.scala | 10 +- .../es/EsConfigBasedRorSettings.scala | 241 +++--------------- .../settings/es/LoadingRorCoreStrategy.scala | 115 +++++++++ .../ror/settings/es/RorBootSettings.scala | 88 +++---- .../beshu/ror/settings/es/RorProperties.scala | 4 +- .../es/RorSettingsSourcesConfig.scala | 80 ++++++ .../ror/settings/es/RorSslSettings.scala | 103 ++++++-- .../es/YamlFileBasedSettingsLoader.scala | 25 +- .../settings/ror/loader/RetryStrategy.scala | 2 +- .../unit/configuration/SslSettingsTest.scala | 2 +- 17 files changed, 435 insertions(+), 323 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/accesscontrol/domain/settings.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala create mode 100644 core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala index 13765b0efc..a62e2e9534 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/indices.scala @@ -28,7 +28,6 @@ import tech.beshu.ror.accesscontrol.domain.ClusterIndexName.Remote.ClusterName import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher import tech.beshu.ror.accesscontrol.matchers.PatternsMatcher.Matchable import tech.beshu.ror.accesscontrol.orders.requestedIndexOrder -import tech.beshu.ror.es.EsEnv import tech.beshu.ror.syntax.* import tech.beshu.ror.utils.RefinedUtils.* import tech.beshu.ror.utils.ScalaOps.* @@ -529,16 +528,3 @@ object IndexAttribute { case object Opened extends IndexAttribute case object Closed extends IndexAttribute } - -final case class RorSettingsIndex(index: IndexName.Full) extends AnyVal { - def toLocal: ClusterIndexName.Local = ClusterIndexName.Local(index) -} -object RorSettingsIndex { - val default: RorSettingsIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))) -} - -final case class RorSettingsFile(file: File) extends AnyVal -object RorSettingsFile { - def default(esEnv: EsEnv): RorSettingsFile = RorSettingsFile(esEnv.configDir / "readonlyrest.yml") -} - diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/settings.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/settings.scala new file mode 100644 index 0000000000..a69efb7fa9 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/domain/settings.scala @@ -0,0 +1,38 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.accesscontrol.domain + +import better.files.File +import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.utils.RefinedUtils.nes + +final case class RorSettingsIndex(index: IndexName.Full) extends AnyVal { + def toLocal: ClusterIndexName.Local = ClusterIndexName.Local(index) +} +object RorSettingsIndex { + val default: RorSettingsIndex = RorSettingsIndex(IndexName.Full(nes(".readonlyrest"))) +} + +final case class RorSettingsFile(file: File) extends AnyVal +object RorSettingsFile { + def default(esEnv: EsEnv): RorSettingsFile = RorSettingsFile(esEnv.configDir / "readonlyrest.yml") +} + +final case class EsConfigFile(file: File) extends AnyVal +object EsConfigFile { + def default(esEnv: EsEnv): EsConfigFile = EsConfigFile(esEnv.configDir / "elasticsearch.yml") +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index f35523f919..d997b3baf5 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -65,8 +65,8 @@ class ReadonlyRest(coreFactory: CoreFactory, loadedMainRorSettings: MainRorSettings, loadedTestRorSettings: Option[TestRorSettings]) = { for { - mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings.rawSettings, esConfigBasedRorSettings.settingsIndex)) - testEngine <- EitherT.right(loadTestEngine(loadedTestRorSettings, esConfigBasedRorSettings.settingsIndex)) + mainEngine <- EitherT(loadRorEngine(loadedMainRorSettings.rawSettings, esConfigBasedRorSettings.settingsSource.settingsIndex)) + testEngine <- EitherT.right(loadTestEngine(loadedTestRorSettings, esConfigBasedRorSettings.settingsSource.settingsIndex)) rorInstance <- createRorInstance(esConfigBasedRorSettings, creators, mainEngine, testEngine, loadedMainRorSettings) } yield rorInstance } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 5ac26d223f..502fb575c4 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -32,8 +32,8 @@ import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.engines.Engines import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.{CoreRefreshSettings, LoadingRorCoreStrategy} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategy} import tech.beshu.ror.settings.ror.source.IndexSettingsSource import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index 380b8a45ff..8e3309b15c 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -19,8 +19,7 @@ package tech.beshu.ror.boot import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRorCoreStrategy +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategy} import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser import tech.beshu.ror.settings.ror.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} import tech.beshu.ror.settings.ror.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} @@ -32,16 +31,13 @@ object SettingsRelatedCreatorsAndLoaders { def create(esConfigBasedRorSettings: EsConfigBasedRorSettings, indexDocumentManager: IndexDocumentManager): SettingsRelatedCreatorsAndLoaders = { - val settingsYamlParser = new RawRorSettingsYamlParser(esConfigBasedRorSettings.settingsMaxSize) - val mainSettingsIndexSource = MainSettingsIndexSource.create( - indexDocumentManager, esConfigBasedRorSettings.settingsIndex, settingsYamlParser - ) - val mainSettingsFileSource = MainSettingsFileSource.create( - esConfigBasedRorSettings.settingsFile, settingsYamlParser - ) - val testSettingsIndexSource = TestSettingsIndexSource.create( - indexDocumentManager, esConfigBasedRorSettings.settingsIndex, settingsYamlParser - ) + val settingsIndex = esConfigBasedRorSettings.settingsSource.settingsIndex + val settingsFile = esConfigBasedRorSettings.settingsSource.settingsFile + val settingsMaxSize = esConfigBasedRorSettings.settingsSource.settingsMaxSize + val settingsYamlParser = new RawRorSettingsYamlParser(settingsMaxSize) + val mainSettingsIndexSource = MainSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) + val mainSettingsFileSource = MainSettingsFileSource.create(settingsFile, settingsYamlParser) + val testSettingsIndexSource = TestSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { case s@LoadingRorCoreStrategy.ForceLoadingFromFile => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala index d3da403ac1..7b104b7be1 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/BaseReloadableEngine.scala @@ -254,7 +254,7 @@ private[engines] abstract class BaseReloadableEngine(val name: String, private def reloadWith(rorSettings: RawRorSettings, expiration: Option[UpdatedExpiration]): EitherT[Task, RawSettingsReloadError, EngineWithSettings] = { - EitherT(boot.loadRorEngine(rorSettings, esConfigBasedRorSettings.settingsIndex)) + EitherT(boot.loadRorEngine(rorSettings, esConfigBasedRorSettings.settingsSource.settingsIndex)) .map { engine => EngineWithSettings( engine = engine, diff --git a/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala b/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala index 09e993abd1..ebeae78055 100644 --- a/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala +++ b/core/src/main/scala/tech/beshu/ror/es/EsEnv.scala @@ -16,7 +16,9 @@ */ package tech.beshu.ror.es -import better.files._ +import better.files.* +import tech.beshu.ror.accesscontrol.domain.EsConfigFile + import scala.util.Try final case class EsEnv(configDir: File, @@ -32,5 +34,5 @@ final case class EsEnv(configDir: File, } } - def elasticsearchYmlFile: File = configDir / "elasticsearch.yml" + def elasticsearchConfig: EsConfigFile = EsConfigFile.default(this) } diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index f500d99ba2..0d53404bbd 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -61,8 +61,8 @@ import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.CoreRefreshSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError @@ -410,6 +410,8 @@ trait LogsShowInstances case CoreRefreshSettings.Enabled(interval) => interval.value.toString() } + implicit val esConfigFileShow: Show[EsConfigFile] = Show.show(_.file.show) + implicit val loadingDelayShow: Show[LoadingDelay] = Show[FiniteDuration].contramap(_.value.value) implicit val loadingAttemptsCountShow: Show[LoadingAttemptsCount] = Show[Int].contramap(_.value.value) @@ -425,8 +427,6 @@ trait LogsShowInstances s"Cannot find elasticsearch settings file: [${file.show}]" case EsConfigBasedRorSettings.LoadingError.MalformedContent(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" - case EsConfigBasedRorSettings.LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled => - s"Cannot use ROR SSL when XPack Security is enabled" } implicit val parsingRorSettingsErrorShow: Show[ParsingRorSettingsError] = Show.show { @@ -448,7 +448,7 @@ trait LogsShowInstances case FileSettingsSource.LoadingError.FileNotExist(file) => s"Cannot find settings file: ${file.pathAsString}" } - implicit val show: Show[StartingFailure] = Show.show(_.message) + implicit val startingFailureShow: Show[StartingFailure] = Show.show(_.message) implicit def loadingSettingsErrorShow[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { case LoadingSettingsError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index 42d1ab1944..a366cace1d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -17,246 +17,63 @@ package tech.beshu.ror.settings.es import better.files.File -import cats.data.{EitherT, NonEmptyList} -import eu.timepit.refined.api.Refined -import eu.timepit.refined.numeric.NonNegative -import eu.timepit.refined.types.string.NonEmptyString -import io.circe.Decoder +import cats.data.EitherT import monix.eval.Task -import squants.information.Information import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} -import tech.beshu.ror.accesscontrol.factory.decoders.common.* +import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.providers.PropertiesProvider -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError.{CannotUseRorSslWhenXPackSecurityIsEnabled, FileNotFound, MalformedContent} -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRorCoreStrategy -import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} -import tech.beshu.ror.utils.yaml.YamlKeyDecoder +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError.{FileNotFound, MalformedContent} -import scala.concurrent.duration.{DurationInt, FiniteDuration} import scala.language.{implicitConversions, postfixOps} -final case class EsConfigBasedRorSettings(boot: RorBootSettings, +final case class EsConfigBasedRorSettings(settingsSource: RorSettingsSourcesConfig, + boot: RorBootSettings, ssl: Option[RorSslSettings], - // todo: rename - settings storeage related - settingsIndex: RorSettingsIndex, - settingsFile: RorSettingsFile, - settingsMaxSize: Information, loadingRorCoreStrategy: LoadingRorCoreStrategy) object EsConfigBasedRorSettings { + sealed trait LoadingError + object LoadingError { + final case class FileNotFound(file: File) extends LoadingError + final case class MalformedContent(file: File, message: String) extends LoadingError + } + def from(esEnv: EsEnv) (implicit systemContext: SystemContext): Task[Either[LoadingError, EsConfigBasedRorSettings]] = { - val configFile = esEnv.elasticsearchYmlFile + val esConfig = esEnv.elasticsearchConfig val result = for { - _ <- EitherT.fromEither[Task](Either.cond(configFile.exists, (), FileNotFound(configFile))) + _ <- EitherT.fromEither[Task](Either.cond(esConfig.file.exists, (), FileNotFound(esConfig.file): LoadingError)) + settingsSource <- loadSettingsSource(esEnv) bootSettings <- loadRorBootSettings(esEnv) + sslSettings <- loadSslSettings(esEnv, settingsSource.settingsFile) loadingRorCoreStrategy <- loadLoadingRorCoreStrategy(esEnv) - settingsFile <- loadRorSettingsFile(esEnv) - settingsIndex <- loadRorSettingsIndex(esEnv) - settingsMaxSize <- loadMaxSizeInformation(esEnv) - xpackSettings <- loadXpackSecuritySettings(esEnv, esEnv.isOssDistribution) - sslSettings <- loadRorSslSettings(esEnv, settingsFile, xpackSettings) - } yield EsConfigBasedRorSettings(bootSettings, sslSettings, settingsIndex, settingsFile, settingsMaxSize, loadingRorCoreStrategy) + } yield EsConfigBasedRorSettings(settingsSource, bootSettings, sslSettings, loadingRorCoreStrategy) result.value } private def loadRorBootSettings(esEnv: EsEnv) - (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, RorBootSettings] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, RorBootSettings] = { EitherT(RorBootSettings.load(esEnv)) - .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - } - - private def loadXpackSecuritySettings(esEnv: EsEnv, ossDistribution: Boolean) - (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, XpackSecuritySettings] = { - EitherT { - Task.delay { - implicit val xpackSettingsDecoder: Decoder[XpackSecuritySettings] = decoders.xpackSettingsDecoder(ossDistribution) - new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) - .loadSettings[XpackSecuritySettings](settingsName = "X-Pack settings") - .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - } - } - } - - private def loadRorSslSettings(esEnv: EsEnv, - rorSettingsFile: RorSettingsFile, - xpackSecurity: XpackSecuritySettings) - (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { - EitherT(RorSslSettings.load(rorSettingsFile, esEnv.elasticsearchYmlFile)) - .leftMap(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - .subflatMap { - case Some(ssl) if xpackSecurity.enabled => - Left(CannotUseRorSslWhenXPackSecurityIsEnabled) - case rorSsl@(Some(_) | None) => - Right(rorSsl) - } - } - - private def loadRorSettingsFile(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { - implicit val decoder: Decoder[RorSettingsFile] = decoders.rorSettingsFileDecoder(esEnv) - load[RorSettingsFile](esEnv, "ROR configuration file name") - } - - private def loadRorSettingsIndex(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { - import decoders.rorSettingsIndexDecoder - load[RorSettingsIndex](esEnv, "ROR configuration index settings") + .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) } private def loadLoadingRorCoreStrategy(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { - implicit val decoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) - load[LoadingRorCoreStrategy](esEnv, "ROR loading core settings") - } - - private def loadMaxSizeInformation(esEnv: EsEnv) - (implicit systemContext: SystemContext) = { - implicit val decoder: Decoder[Information] = decoders.settingsMaxSizeDecoder() - load[Information](esEnv, "ROR settings max size") - } - - private def load[T: Decoder](esEnv: EsEnv, settingsName: String) - (implicit systemContext: SystemContext): EitherT[Task, MalformedContent, T] = { - EitherT.fromEither[Task] { - val loader = new YamlFileBasedSettingsLoader(esEnv.elasticsearchYmlFile) - for { - strategy <- loader - .loadSettings[T](settingsName) - .left.map(error => MalformedContent(esEnv.elasticsearchYmlFile, error.message)) - } yield strategy - } - } - - sealed trait LoadingRorCoreStrategy - object LoadingRorCoreStrategy { - case object ForceLoadingFromFile extends LoadingRorCoreStrategy - final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, - coreRefreshSettings: CoreRefreshSettings) - extends LoadingRorCoreStrategy + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, LoadingRorCoreStrategy] = { + EitherT(LoadingRorCoreStrategy.load(esEnv)) + .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) } - final case class LoadingRetryStrategySettings(attemptsInterval: LoadingAttemptsInterval, - attemptsCount: LoadingAttemptsCount, - delay: LoadingDelay) - object LoadingRetryStrategySettings { - - final case class LoadingAttemptsCount(value: Int Refined NonNegative) extends AnyVal - object LoadingAttemptsCount { - def unsafeFrom(value: Int): LoadingAttemptsCount = LoadingAttemptsCount(Refined.unsafeApply(value)) - - val zero: LoadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(0) - } - - final case class LoadingAttemptsInterval(value: NonNegativeFiniteDuration) extends AnyVal - object LoadingAttemptsInterval { - def unsafeFrom(value: FiniteDuration): LoadingAttemptsInterval = LoadingAttemptsInterval(value.toRefinedNonNegativeUnsafe) - } - - final case class LoadingDelay(value: NonNegativeFiniteDuration) extends AnyVal - object LoadingDelay { - val none: LoadingDelay = unsafeFrom(0 seconds) - - def unsafeFrom(value: FiniteDuration): LoadingDelay = LoadingDelay(value.toRefinedNonNegativeUnsafe) - } - } - - sealed trait CoreRefreshSettings - object CoreRefreshSettings { - case object Disabled extends CoreRefreshSettings - final case class Enabled(refreshInterval: PositiveFiniteDuration) extends CoreRefreshSettings - } - - private final case class XpackSecuritySettings(enabled: Boolean) - - sealed trait LoadingError - object LoadingError { - final case class FileNotFound(file: File) extends LoadingError - final case class MalformedContent(file: File, message: String) extends LoadingError - case object CannotUseRorSslWhenXPackSecurityIsEnabled extends LoadingError + private def loadSettingsSource(esEnv: EsEnv) + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, RorSettingsSourcesConfig] = { + EitherT(RorSettingsSourcesConfig.from(esEnv)) + .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) } - private object decoders { - implicit def loadRorCoreStrategyDecoder(esEnv: EsEnv) - (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategy] = { - YamlKeyDecoder[Boolean]( - path = NonEmptyList.of("readonlyrest", "force_load_from_file"), - default = false - ) flatMap { - case true => - Decoder.const(LoadingRorCoreStrategy.ForceLoadingFromFile) - case false => - for { - loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) - coreRefreshIntervalSettings <- loadCoreRefreshSettings(systemContext.propertiesProvider) - } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback( - loadingRetryStrategySettings, coreRefreshIntervalSettings - ) - } - } - - implicit val rorSettingsIndexDecoder: Decoder[RorSettingsIndex] = { - implicit val indexNameDecoder: Decoder[RorSettingsIndex] = - Decoder[NonEmptyString] - .map(IndexName.Full.apply) - .map(RorSettingsIndex.apply) - YamlKeyDecoder[RorSettingsIndex]( - path = NonEmptyList.of("readonlyrest", "settings_index"), - default = RorSettingsIndex.default - ) - } - - implicit def rorSettingsFileDecoder(esEnv: EsEnv) - (implicit systemContext: SystemContext): Decoder[RorSettingsFile] = - Decoder.instance(_ => Right( - RorProperties - .rorSettingsCustomFile(systemContext.propertiesProvider) - .getOrElse(RorSettingsFile.default(esEnv)) - )) - - implicit def settingsMaxSizeDecoder() - (implicit systemContext: SystemContext): Decoder[Information] = { - Decoder.instance(_ => Right( - RorProperties.rorSettingsMaxSize(systemContext.propertiesProvider) - )) - } - - def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecuritySettings] = { - if (isOssDistribution) { - Decoder.const(XpackSecuritySettings(enabled = false)) - } else { - val booleanDecoder = YamlKeyDecoder[Boolean]( - path = NonEmptyList.of("xpack", "security", "enabled"), - default = true - ) - val stringDecoder = YamlKeyDecoder[String]( - path = NonEmptyList.of("xpack", "security", "enabled"), - default = "true" - ) map { - _.toBoolean - } - (booleanDecoder or stringDecoder) map XpackSecuritySettings.apply - } - } - - private def loadLoadingRetryStrategySettings(propertiesProvider: PropertiesProvider): Decoder[LoadingRetryStrategySettings] = { - for { - loadingAttemptsInterval <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(propertiesProvider))) - loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) - loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) - } yield LoadingRetryStrategySettings( - loadingAttemptsInterval, - loadingAttemptsCount, - loadingDelay - ) - } + private def loadSslSettings(esEnv: EsEnv, rorSettingsFile: RorSettingsFile) + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { + EitherT(RorSslSettings.load(esEnv, rorSettingsFile)) + .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) } - private def loadCoreRefreshSettings(propertiesProvider: PropertiesProvider): Decoder[CoreRefreshSettings] = { - Decoder.instance(_ => Right(RorProperties.rorCoreRefreshSettings(propertiesProvider))) - } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala new file mode 100644 index 0000000000..03798a791e --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala @@ -0,0 +1,115 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.es + +import cats.data.NonEmptyList +import eu.timepit.refined.api.Refined +import eu.timepit.refined.numeric.NonNegative +import io.circe.Decoder +import monix.eval.Task +import tech.beshu.ror.SystemContext +import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.providers.PropertiesProvider +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} +import tech.beshu.ror.utils.yaml.YamlKeyDecoder + +import scala.concurrent.duration.{DurationInt, FiniteDuration} +import scala.language.{implicitConversions, postfixOps} + +sealed trait LoadingRorCoreStrategy +object LoadingRorCoreStrategy extends YamlFileBasedSettingsLoaderSupport { + + case object ForceLoadingFromFile extends LoadingRorCoreStrategy + final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, + coreRefreshSettings: CoreRefreshSettings) + extends LoadingRorCoreStrategy + + final case class LoadingRetryStrategySettings(attemptsInterval: LoadingAttemptsInterval, + attemptsCount: LoadingAttemptsCount, + delay: LoadingDelay) + object LoadingRetryStrategySettings { + + final case class LoadingAttemptsCount(value: Int Refined NonNegative) extends AnyVal + object LoadingAttemptsCount { + def unsafeFrom(value: Int): LoadingAttemptsCount = LoadingAttemptsCount(Refined.unsafeApply(value)) + + val zero: LoadingAttemptsCount = LoadingAttemptsCount.unsafeFrom(0) + } + + final case class LoadingAttemptsInterval(value: NonNegativeFiniteDuration) extends AnyVal + object LoadingAttemptsInterval { + def unsafeFrom(value: FiniteDuration): LoadingAttemptsInterval = LoadingAttemptsInterval(value.toRefinedNonNegativeUnsafe) + } + + final case class LoadingDelay(value: NonNegativeFiniteDuration) extends AnyVal + object LoadingDelay { + val none: LoadingDelay = unsafeFrom(0 seconds) + + def unsafeFrom(value: FiniteDuration): LoadingDelay = LoadingDelay(value.toRefinedNonNegativeUnsafe) + } + } + + sealed trait CoreRefreshSettings + object CoreRefreshSettings { + case object Disabled extends CoreRefreshSettings + final case class Enabled(refreshInterval: PositiveFiniteDuration) extends CoreRefreshSettings + } + + def load(esEnv: EsEnv) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, LoadingRorCoreStrategy]] = { + implicit val decoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) + loadSetting[LoadingRorCoreStrategy](esEnv, "ROR loading core strategy settings") + } + + private object decoders { + implicit def loadRorCoreStrategyDecoder(esEnv: EsEnv) + (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategy] = { + YamlKeyDecoder[Boolean]( + path = NonEmptyList.of("readonlyrest", "force_load_from_file"), + default = false + ) flatMap { + case true => + Decoder.const(LoadingRorCoreStrategy.ForceLoadingFromFile) + case false => + for { + loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) + coreRefreshIntervalSettings <- loadCoreRefreshSettings(systemContext.propertiesProvider) + } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback( + loadingRetryStrategySettings, coreRefreshIntervalSettings + ) + } + } + + private def loadCoreRefreshSettings(propertiesProvider: PropertiesProvider): Decoder[CoreRefreshSettings] = { + Decoder.instance(_ => Right(RorProperties.rorCoreRefreshSettings(propertiesProvider))) + } + + private def loadLoadingRetryStrategySettings(propertiesProvider: PropertiesProvider): Decoder[LoadingRetryStrategySettings] = { + for { + loadingAttemptsInterval <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsInterval(propertiesProvider))) + loadingAttemptsCount <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingsLoadingAttemptsCount(propertiesProvider))) + loadingDelay <- Decoder.instance(_ => Right(RorProperties.atStartupRorIndexSettingLoadingDelay(propertiesProvider))) + } yield LoadingRetryStrategySettings( + loadingAttemptsInterval, + loadingAttemptsCount, + loadingDelay + ) + } + } + +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala index 04278dc0ba..210a76624d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala @@ -28,13 +28,12 @@ import tech.beshu.ror.utils.yaml.YamlKeyDecoder final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, rorFailedToStartResponse: RorFailedToStartResponse) -object RorBootSettings { +object RorBootSettings extends YamlFileBasedSettingsLoaderSupport { def load(env: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootSettings]] = Task { - implicit val rorBootSettingsDecoder: Decoder[RorBootSettings] = Decoders.decoder - new YamlFileBasedSettingsLoader(env.elasticsearchYmlFile) - .loadSettings[RorBootSettings](settingsName = "ROR boot settings") + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootSettings]] = { + implicit val rorBootSettingsDecoder: Decoder[RorBootSettings] = decoders.rorBootSettingsDecoder + loadSetting[RorBootSettings](env, "ROR boot settings") } final case class RorNotStartedResponse(httpCode: RorNotStartedResponse.HttpCode) @@ -54,56 +53,57 @@ object RorBootSettings { case object `503` extends HttpCode } } -} -private object Decoders { + private object decoders { - object consts { - val rorSection = "readonlyrest" - val rorNotStartedResponseCode = "not_started_response_code" - val rorFailedTpStartResponseCode = "failed_to_start_response_code" - } + object consts { + val rorSection = "readonlyrest" + val rorNotStartedResponseCode = "not_started_response_code" + val rorFailedTpStartResponseCode = "failed_to_start_response_code" + } - def decoder: Decoder[RorBootSettings] = Decoder.instance { c => - for { - notStarted <- c.as[RorNotStartedResponse] - failedToStart <- c.as[RorFailedToStartResponse] - } yield RorBootSettings(notStarted, failedToStart) - } + def rorBootSettingsDecoder: Decoder[RorBootSettings] = Decoder.instance { c => + for { + notStarted <- c.as[RorNotStartedResponse] + failedToStart <- c.as[RorFailedToStartResponse] + } yield RorBootSettings(notStarted, failedToStart) + } - private implicit val rorNotStartedResponseDecoder: Decoder[RorNotStartedResponse] = { - val segments = NonEmptyList.of(consts.rorSection, consts.rorNotStartedResponseCode) + private implicit val rorNotStartedResponseDecoder: Decoder[RorNotStartedResponse] = { + val segments = NonEmptyList.of(consts.rorSection, consts.rorNotStartedResponseCode) - implicit val httpCodeDecoder: Decoder[RorNotStartedResponse.HttpCode] = Decoder.decodeInt.emap { - case 403 => Right(RorNotStartedResponse.HttpCode.`403`) - case 503 => Right(RorNotStartedResponse.HttpCode.`503`) - case other => Left( - s"Unsupported response code [${other.show}] for ${segments.toList.mkString(".").show}. Supported response codes are: 403, 503." + implicit val httpCodeDecoder: Decoder[RorNotStartedResponse.HttpCode] = Decoder.decodeInt.emap { + case 403 => Right(RorNotStartedResponse.HttpCode.`403`) + case 503 => Right(RorNotStartedResponse.HttpCode.`503`) + case other => Left( + s"Unsupported response code [${other.show}] for ${segments.toList.mkString(".").show}. Supported response codes are: 403, 503." + ) + } + + YamlKeyDecoder[RorNotStartedResponse.HttpCode]( + path = segments, + default = RorNotStartedResponse.HttpCode.`403` ) + .map(RorNotStartedResponse.apply) } - YamlKeyDecoder[RorNotStartedResponse.HttpCode]( - path = segments, - default = RorNotStartedResponse.HttpCode.`403` - ) - .map(RorNotStartedResponse.apply) - } + private implicit val rorFailedToStartResponseDecoder: Decoder[RorFailedToStartResponse] = { + val segments = NonEmptyList.of(consts.rorSection, consts.rorFailedTpStartResponseCode) - private implicit val rorFailedToStartResponseDecoder: Decoder[RorFailedToStartResponse] = { - val segments = NonEmptyList.of(consts.rorSection, consts.rorFailedTpStartResponseCode) + implicit val httpCodeDecoder: Decoder[RorFailedToStartResponse.HttpCode] = Decoder.decodeInt.emap { + case 403 => Right(RorFailedToStartResponse.HttpCode.`403`) + case 503 => Right(RorFailedToStartResponse.HttpCode.`503`) + case other => Left( + s"Unsupported response code [${other.show}] for ${segments.toList.mkString(".").show}. Supported response codes are: 403, 503." + ) + } - implicit val httpCodeDecoder: Decoder[RorFailedToStartResponse.HttpCode] = Decoder.decodeInt.emap { - case 403 => Right(RorFailedToStartResponse.HttpCode.`403`) - case 503 => Right(RorFailedToStartResponse.HttpCode.`503`) - case other => Left( - s"Unsupported response code [${other.show}] for ${segments.toList.mkString(".").show}. Supported response codes are: 403, 503." + YamlKeyDecoder[RorFailedToStartResponse.HttpCode]( + path = segments, + default = RorFailedToStartResponse.HttpCode.`403` ) + .map(RorFailedToStartResponse.apply) } - - YamlKeyDecoder[RorFailedToStartResponse.HttpCode]( - path = segments, - default = RorFailedToStartResponse.HttpCode.`403` - ) - .map(RorFailedToStartResponse.apply) } + } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala index cbd5fbc337..29bf52248a 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala @@ -27,8 +27,8 @@ import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.providers.PropertiesProvider.PropName -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.CoreRefreshSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings.* +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.RefinedUtils.* diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala new file mode 100644 index 0000000000..6bdffb838c --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala @@ -0,0 +1,80 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.settings.es + +import cats.data.NonEmptyList +import eu.timepit.refined.types.string.NonEmptyString +import io.circe.Decoder +import monix.eval.Task +import squants.information.Information +import tech.beshu.ror.SystemContext +import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} +import tech.beshu.ror.accesscontrol.factory.decoders.common.* +import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.utils.yaml.YamlKeyDecoder + +final case class RorSettingsSourcesConfig(settingsIndex: RorSettingsIndex, + settingsFile: RorSettingsFile, + settingsMaxSize: Information) + +object RorSettingsSourcesConfig extends YamlFileBasedSettingsLoaderSupport { + + def from(esEnv: EsEnv) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorSettingsSourcesConfig]] = { + implicit val decoder: Decoder[RorSettingsSourcesConfig] = for { + rorSettingsIndex <- decoders.rorSettingsIndexDecoder + rorSettingsFile <- decoders.rorSettingsFileDecoder(esEnv) + rorSettingsMaxSize <- decoders.settingsMaxSizeDecoder() + } yield RorSettingsSourcesConfig( + rorSettingsIndex, + rorSettingsFile, + rorSettingsMaxSize + ) + loadSetting[RorSettingsSourcesConfig](esEnv, "ROR settings source config") + } + + private object decoders { + + val rorSettingsIndexDecoder: Decoder[RorSettingsIndex] = { + implicit val indexNameDecoder: Decoder[RorSettingsIndex] = + Decoder[NonEmptyString] + .map(IndexName.Full.apply) + .map(RorSettingsIndex.apply) + YamlKeyDecoder[RorSettingsIndex]( + path = NonEmptyList.of("readonlyrest", "settings_index"), + default = RorSettingsIndex.default + ) + } + + def rorSettingsFileDecoder(esEnv: EsEnv) + (implicit systemContext: SystemContext): Decoder[RorSettingsFile] = + Decoder.instance(_ => Right( + RorProperties + .rorSettingsCustomFile(systemContext.propertiesProvider) + .getOrElse(RorSettingsFile.default(esEnv)) + )) + + def settingsMaxSizeDecoder() + (implicit systemContext: SystemContext): Decoder[Information] = { + Decoder.instance(_ => Right( + RorProperties.rorSettingsMaxSize(systemContext.propertiesProvider) + )) + } + + } + +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index 991c5e9da0..1991faff7d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -17,18 +17,21 @@ package tech.beshu.ror.settings.es import better.files.* +import cats.data.{EitherT, NonEmptyList} import io.circe.{Decoder, DecodingFailure, HCursor} import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.RorSettingsFile +import tech.beshu.ror.accesscontrol.domain.{EsConfigFile, RorSettingsFile} import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers +import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.SslSettings.* import tech.beshu.ror.utils.SSLCertHelper +import tech.beshu.ror.utils.yaml.YamlKeyDecoder sealed trait RorSslSettings -object RorSslSettings extends Logging { +object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { final case class OnlyExternalSslSettings(ssl: ExternalSslSettings) extends RorSslSettings final case class OnlyInternodeSslSettings(ssl: InternodeSslSettings) extends RorSslSettings @@ -57,40 +60,92 @@ object RorSslSettings extends Logging { } } - def load(rorSettingsFile: RorSettingsFile, esConfigFile: File) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = Task { - implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esConfigFile.parent) - loadSslSettingsFrom(esConfigFile) - .fold( - error => Left(error), - { - case None => - logger.info(s"Cannot find ROR SSL settings in ${esConfigFile.show} ...") - fallbackToRorSettingsFile(rorSettingsFile) - case Some(ssl) => - Right(Some(ssl)) - } - ) + def load(esEnv: EsEnv, + rorSettingsFile: RorSettingsFile) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = { + val result = for { + xpackSecuritySettings <- loadXpackSecuritySettings(esEnv) + rorSslSettings <- loadRorSslSetting(esEnv.elasticsearchConfig, rorSettingsFile, xpackSecuritySettings) + } yield rorSslSettings + result.value + } + + private def loadXpackSecuritySettings(esEnv: EsEnv) + (implicit systemContext: SystemContext): EitherT[Task, MalformedSettings, XpackSecuritySettings] = { + EitherT { + implicit val decoder: Decoder[XpackSecuritySettings] = xpackSettingsDecoder(esEnv.isOssDistribution) + loadSetting[XpackSecuritySettings](esEnv, "X-Pack settings") + } + } + + private def loadRorSslSetting(esConfigFile: EsConfigFile, + rorSettingsFile: RorSettingsFile, + xpackSecuritySettings: XpackSecuritySettings) + (implicit systemContext: SystemContext): EitherT[Task, MalformedSettings, Option[RorSslSettings]] = { + implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esConfigFile.file.parent) + loadSslSettingsFrom(esConfigFile.file) + .flatMap { + case None => + fallbackToRorSettingsFile(rorSettingsFile) + case Some(ssl) => + EitherT.rightT(Some(ssl)) + } + .subflatMap { + case Some(ssl) if xpackSecuritySettings.enabled => + Left(MalformedSettings("Cannot use ROR SSL when XPack Security is enabled")) + case rorSsl@(Some(_) | None) => + Right(rorSsl) + } } private def fallbackToRorSettingsFile(rorSettingsFile: RorSettingsFile) (implicit decoder: Decoder[Option[RorSslSettings]], - systemContext: SystemContext) = { + systemContext: SystemContext): EitherT[Task, MalformedSettings, Option[RorSslSettings]] = { val settingsFile = rorSettingsFile.file - logger.info(s"... trying: ${settingsFile.show}") if (settingsFile.exists) { - loadSslSettingsFrom(settingsFile) + for { + _ <- lift(logger.warn(s"Defining SSL settings in ReadonlyREST file is deprecated and will be removed in the future. Move your ReadonlyREST SSL settings to Elasticsearch config file. See https://docs.readonlyrest.com/elasticsearch#encryption for details")) + settings <- loadSslSettingsFrom(settingsFile) + } yield settings } else { - Right(None) + EitherT.rightT(None) } } private def loadSslSettingsFrom(settingsFile: File) (implicit decoder: Decoder[Option[RorSslSettings]], systemContext: SystemContext) = { - new YamlFileBasedSettingsLoader(settingsFile) - .loadSettings[Option[RorSslSettings]](settingsName = "ROR SSL settings") + for { + _ <- lift(logger.info(s"Trying to load ROR SSL settings from '${settingsFile.show}' file ...")) + settings <- EitherT(loadSetting[Option[RorSslSettings]](settingsFile, "ROR SSL settings")) + _ <- lift(logger.info(settings match { + case Some(_) => s"ROR SSL settings loaded from '${settingsFile.show}' file." + case None => s"No ROR SSL settings found in '${settingsFile.show}' file." + })) + } yield settings } + + private final case class XpackSecuritySettings(enabled: Boolean) + + private def xpackSettingsDecoder(isOssDistribution: Boolean): Decoder[XpackSecuritySettings] = { + if (isOssDistribution) { + Decoder.const(XpackSecuritySettings(enabled = false)) + } else { + val booleanDecoder = YamlKeyDecoder[Boolean]( + path = NonEmptyList.of("xpack", "security", "enabled"), + default = true + ) + val stringDecoder = YamlKeyDecoder[String]( + path = NonEmptyList.of("xpack", "security", "enabled"), + default = "true" + ) map { + _.toBoolean + } + (booleanDecoder or stringDecoder) map XpackSecuritySettings.apply + } + } + + private def lift[T](value: => T): EitherT[Task, MalformedSettings, T] = EitherT.rightT(value) } sealed trait SslSettings { @@ -310,7 +365,7 @@ private object SslDecoders extends Logging { } private def sslInternodeSettingsDecoder(basePath: File, - fipsMode: FipsMode): Decoder[Option[InternodeSslSettings]] = Decoder.instance { c => + fipsMode: FipsMode): Decoder[Option[InternodeSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { certificateVerification <- c.downField(consts.certificateVerification).as[Option[Boolean]] @@ -332,7 +387,7 @@ private object SslDecoders extends Logging { } private def sslExternalSettingsDecoder(basePath: File, - fipsMode: FipsMode): Decoder[Option[ExternalSslSettings]] = Decoder.instance { c => + fipsMode: FipsMode): Decoder[Option[ExternalSslSettings]] = Decoder.instance { c => whenEnabled(c) { for { verification <- c.downField(consts.verification).as[Option[Boolean]] diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala index 403dc56b17..b376269fc4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala @@ -18,9 +18,11 @@ package tech.beshu.ror.settings.es import better.files.File import io.circe.{Decoder, DecodingFailure, Json} +import monix.eval.Task import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.variables.transformation.TransformationCompiler import tech.beshu.ror.accesscontrol.factory.JsonStaticVariablesResolver +import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson import tech.beshu.ror.utils.yaml.YamlParser @@ -66,4 +68,25 @@ final class YamlFileBasedSettingsLoader(file: File) } } -final case class MalformedSettings(message: String) \ No newline at end of file +final case class MalformedSettings(message: String) + +private[es] trait YamlFileBasedSettingsLoaderSupport { + + protected def loadSetting[T: Decoder](esEnv: EsEnv, settingsName: String) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, T]] = { + loadSetting(esEnv.elasticsearchConfig.file, settingsName) + } + + protected def loadSetting[T: Decoder](file: File, settingsName: String) + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, T]] = { + Task.delay { + val loader = new YamlFileBasedSettingsLoader(file) + for { + strategy <- loader + .loadSettings[T](settingsName) + .left.map(error => MalformedSettings(error.message)) + } yield strategy + } + } + +} diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index 21a1975866..e9a49a7ab4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -22,7 +22,7 @@ import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingRetryStrategySettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings trait RetryStrategy { def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala index 90d347578f..147c3cbdad 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala @@ -218,8 +218,8 @@ class SslSettingsTest private def loadRorSslSettings(settingsFolderPath: String) = { RorSslSettings .load( + getResourcePath(s"$settingsFolderPath/elasticsearch.yml"), RorSettingsFile(getResourcePath(s"$settingsFolderPath/readonlyrest.yml")), - getResourcePath(s"$settingsFolderPath/elasticsearch.yml") ) .runSyncUnsafe() } From 66265a58321c976b76d37e7f694b7b1abcbe4c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 8 Oct 2025 18:09:03 +0200 Subject: [PATCH 042/103] fixed messages --- core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala | 4 +++- .../scala/tech/beshu/ror/settings/es/RorSslSettings.scala | 5 ++++- .../ror/settings/ror/loader/StartingRorSettingsLoader.scala | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 502fb575c4..1a3534a722 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -59,7 +59,6 @@ class RorInstance private(boot: ReadonlyRest, import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} import creators.* - logger.info("ReadonlyREST was loaded ...") private val reloadTaskState: AtomicReference[ReloadTaskState] = new AtomicReference(ReloadTaskState.NotInitiated) mode match { @@ -86,6 +85,8 @@ class RorInstance private(boot: ReadonlyRest, private val testSettingsRestApi = testSettingsApiCreator.create(this) private val authMockRestApi = new AuthMockApi(rorInstance = this) + logger.info("ReadonlyREST was loaded ...") + def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) def mainSettingsApi: MainSettingsApi = mainSettingsRestApi @@ -164,6 +165,7 @@ class RorInstance private(boot: ReadonlyRest, } } + // todo: do we need all of these messages private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) (implicit requestId: RequestId): CancelableWithRequestId = { diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index 1991faff7d..de1d44325e 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -104,8 +104,11 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { val settingsFile = rorSettingsFile.file if (settingsFile.exists) { for { - _ <- lift(logger.warn(s"Defining SSL settings in ReadonlyREST file is deprecated and will be removed in the future. Move your ReadonlyREST SSL settings to Elasticsearch config file. See https://docs.readonlyrest.com/elasticsearch#encryption for details")) settings <- loadSslSettingsFrom(settingsFile) + _ <- lift(settings match { + case None => logger.warn(s"Defining SSL settings in ReadonlyREST file is deprecated and will be removed in the future. Move your ReadonlyREST SSL settings to Elasticsearch config file. See https://docs.readonlyrest.com/elasticsearch#encryption for details") + case Some(_) => + }) } yield settings } else { EitherT.rightT(None) diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala index 570ba9546c..5b7aa0799d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/StartingRorSettingsLoader.scala @@ -36,7 +36,7 @@ trait StartingRorSettingsLoader { _ <- EitherT.liftTask(logger.info(s"Loading ReadonlyREST $settingsDescription ...")) loadedSettings <- EitherT(source.load()) .biSemiflatTap( - error => logger.dError(s"Loading ReadonlyREST $settingsDescription failed: ${error.show}"), + error => logger.dInfo(s"Loading ReadonlyREST $settingsDescription failed: ${error.show}"), settings => logger.dDebug(s"Loaded ReadonlyREST $settingsDescription:\n${settings.show}") ) .leftMap(error => error.show) From 8b24001ab288bc1a2a4e4a8a504483d64891d686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 9 Oct 2025 10:20:06 +0200 Subject: [PATCH 043/103] wip --- .../tech/beshu/ror/boot/ReadonlyRest.scala | 15 +- .../tech/beshu/ror/boot/RorInstance.scala | 171 ++++-------------- .../ror/boot/RorSettingsAutoReloader.scala | 163 +++++++++++++++++ .../settings/ror/loader/RetryStrategy.scala | 4 +- .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - 36 files changed, 204 insertions(+), 181 deletions(-) create mode 100644 core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala diff --git a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala index d997b3baf5..3640c428c1 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/ReadonlyRest.scala @@ -92,11 +92,11 @@ class ReadonlyRest(coreFactory: CoreFactory, TestEngine.Configured( engine = loadedEngine, settings = testSettings.rawSettings, - expiration = expirationFrom(testSettings.expiration) + expiration = TestEngine.Expiration(testSettings.expiration.ttl, testSettings.expiration.validTo) ) case Left(startingFailure) => logger.error(s"Unable to start test engine. Cause: ${startingFailure.message.show}. Test settings engine will be marked as invalidated.") - TestEngine.Invalidated(testSettings.rawSettings, expirationFrom(testSettings.expiration)) + invalidatedTestEngine(testSettings) } } yield testEngine } @@ -104,13 +104,14 @@ class ReadonlyRest(coreFactory: CoreFactory, private def loadInvalidatedTestEngine(testSettings: TestRorSettings) = { Task .delay(authServicesMocksProvider.update(testSettings.mocks)) - .map { _ => - TestEngine.Invalidated(testSettings.rawSettings, expirationFrom(testSettings.expiration)) - } + .map { case () => invalidatedTestEngine(testSettings) } } - private def expirationFrom(expiration: TestRorSettings.Expiration): TestEngine.Expiration = { - TestEngine.Expiration(expiration.ttl, expiration.validTo) + private def invalidatedTestEngine(testSettings: TestRorSettings) = { + TestEngine.Invalidated( + testSettings.rawSettings, + TestEngine.Expiration(testSettings.expiration.ttl, testSettings.expiration.validTo) + ) } private def createRorInstance(esConfigBasedRorSettings: EsConfigBasedRorSettings, diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 1a3534a722..b3a99f4144 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -16,13 +16,11 @@ */ package tech.beshu.ror.boot -import cats.Show import cats.effect.Resource -import cats.implicits.toShow import cats.syntax.either.* import monix.catnap.Semaphore import monix.eval.Task -import monix.execution.{Cancelable, Scheduler} +import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.blocks.mocks.{AuthServicesMocks, MocksProvider} @@ -31,7 +29,6 @@ import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategy} import tech.beshu.ror.settings.ror.source.IndexSettingsSource @@ -41,7 +38,6 @@ import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant -import java.util.concurrent.atomic.AtomicReference class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, @@ -56,16 +52,11 @@ class RorInstance private(boot: ReadonlyRest, extends Logging { import RorInstance.* - import RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} import creators.* - private val reloadTaskState: AtomicReference[ReloadTaskState] = new AtomicReference(ReloadTaskState.NotInitiated) - - mode match { - case Mode.WithPeriodicIndexCheck(interval) => - scheduleEnginesReload(interval) - case Mode.NoPeriodicIndexCheck => - logger.info(s"[CLUSTERWIDE SETTINGS] Scheduling in-index settings check disabled") + private val settingsAutoReloader = mode match { + case Mode.WithPeriodicIndexCheck(interval) => new EnabledRorSettingsAutoReloader(interval, this) + case Mode.NoPeriodicIndexCheck => DisabledRorSettingsAutoReloader } private val theMainSettingsEngine = mainSettingsBasedReloadableEngineCreator.create( @@ -85,8 +76,9 @@ class RorInstance private(boot: ReadonlyRest, private val testSettingsRestApi = testSettingsApiCreator.create(this) private val authMockRestApi = new AuthMockApi(rorInstance = this) - logger.info("ReadonlyREST was loaded ...") - + settingsAutoReloader.start() + logger.info("ReadonlyREST was loaded!") + def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) def mainSettingsApi: MainSettingsApi = mainSettingsRestApi @@ -130,86 +122,14 @@ class RorInstance private(boot: ReadonlyRest, implicit val requestId: RequestId = RequestId("ES sigterm") for { _ <- Task.delay(logger.info("ReadonlyREST is stopping ...")) - currentState <- Task.delay(reloadTaskState.getAndSet(ReloadTaskState.Stopped)) - _ <- Task.delay(currentState match { - case ReloadTaskState.NotInitiated => // do nothing - case ReloadTaskState.Running(cancelable) => cancelable.cancel() - case ReloadTaskState.Stopped => // do nothing - }) + _ <- settingsAutoReloader.stop() _ <- theTestSettingsEngine.stop() _ <- theMainSettingsEngine.stop() _ <- Task.delay(logger.info("ReadonlyREST is stopped!")) } yield () } - private def scheduleEnginesReload(interval: PositiveFiniteDuration): Unit = { - val reloadTask = { (requestId: RequestId) => - Task.sequence { - Seq( - tryMainEngineReload(requestId).map(result => (SettingsType.Main, result)), - tryTestEngineReload(requestId).map(result => (SettingsType.Test, result)) - ) - } - } - scheduleNextIfNotStopping(interval, reloadTask) - } - - private def scheduleNextIfNotStopping(interval: PositiveFiniteDuration, - reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Unit = { - implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) - val nextTask = scheduleIndexSettingsChecking(interval, reloadTask) - trySetNextReloadTask(nextTask) match { - case ReloadTaskState.NotInitiated => // nothing to do - case ReloadTaskState.Running(_) => // nothing to do - case ReloadTaskState.Stopped => nextTask.cancel() - } - } - - // todo: do we need all of these messages - private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, - reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) - (implicit requestId: RequestId): CancelableWithRequestId = { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check within ${interval.show}") - val cancellable = scheduler.scheduleOnce(interval.value) { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") - reloadTask(requestId) - .runAsync { - case Right(reloadResults) => - reloadResults.foreach(logSettingsReloadResult) - scheduleNextIfNotStopping(interval, reloadTask) - case Left(ex) => - logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) - scheduleNextIfNotStopping(interval, reloadTask) - } - } - new CancelableWithRequestId(cancellable, requestId) - } - - private def trySetNextReloadTask(nextTask: CancelableWithRequestId) = { - reloadTaskState.updateAndGet { - case ReloadTaskState.NotInitiated | ReloadTaskState.Running(_) => - ReloadTaskState.Running(nextTask) - case ReloadTaskState.Stopped => - ReloadTaskState.Stopped - } - } - - private def logSettingsReloadResult(settingsReloadResult: (SettingsType, Either[ScheduledReloadError, Unit])) - (implicit requestId: RequestId): Unit = settingsReloadResult match { - case (_, Right(())) => - case (name, Left(ReloadingInProgress)) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Reloading of ${name.show} engine in progress ... skipping") - case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ${name.show} settings are up to date. Nothing to reload.") - case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Stopping periodic ${name.show} settings check - application is being stopped") - case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") - case (name, Left(EngineReloadError(IndexSettingsReloadError.IndexLoadingSettingsError(error)))) => - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") - } - - private def tryMainEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { + private [boot] def tryMainEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { withGuard(mainReloadInProgress) { theMainSettingsEngine .reloadEngineUsingIndexSettingsWithoutPermit()(requestId) @@ -218,7 +138,7 @@ class RorInstance private(boot: ReadonlyRest, } } - private def tryTestEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { + private [boot] def tryTestEngineReload(requestId: RequestId): Task[Either[ScheduledReloadError, Unit]] = { withGuard(testReloadInProgress) { theTestSettingsEngine .reloadEngineUsingIndexSettingsWithoutPermit()(requestId) @@ -226,7 +146,8 @@ class RorInstance private(boot: ReadonlyRest, } } - private def withGuard(semaphore: Semaphore[Task])(action: => Task[Either[ScheduledReloadError, Unit]]) = { + private def withGuard(semaphore: Semaphore[Task]) + (action: => Task[Either[ScheduledReloadError, Unit]]) = { val criticalSection = Resource.make(semaphore.tryAcquire) { case true => semaphore.release @@ -249,18 +170,6 @@ object RorInstance { testEngine: ReadonlyRest.TestEngine) (implicit systemContext: SystemContext, scheduler: Scheduler): Task[RorInstance] = { - val mode = modeFrom(esConfigBasedRorSettings.loadingRorCoreStrategy) - createInstance(boot, esConfigBasedRorSettings, creators, mode, mainEngine, testEngine) - } - - private def createInstance(boot: ReadonlyRest, - esConfigBasedRorSettings: EsConfigBasedRorSettings, - creators: SettingsRelatedCreators, - mode: RorInstance.Mode, - mainEngine: ReadonlyRest.MainEngine, - testEngine: ReadonlyRest.TestEngine) - (implicit systemContext: SystemContext, - scheduler: Scheduler) = { for { isReloadInProgressSemaphore <- Semaphore[Task](1) isTestReloadInProgressSemaphore <- Semaphore[Task](1) @@ -268,7 +177,7 @@ object RorInstance { boot = boot, esConfigBasedRorSettings = esConfigBasedRorSettings, creators = creators, - mode = mode, + mode = modeFrom(esConfigBasedRorSettings.loadingRorCoreStrategy), mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, testInitialEngine = testEngine, @@ -296,30 +205,38 @@ object RorInstance { sealed trait IndexSettingsReloadWithUpdateError object IndexSettingsReloadWithUpdateError { - final case class ReloadError(undefined: RawSettingsReloadError) extends IndexSettingsReloadWithUpdateError - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsReloadWithUpdateError + final case class ReloadError(undefined: RawSettingsReloadError) + extends IndexSettingsReloadWithUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + extends IndexSettingsReloadWithUpdateError } sealed trait IndexSettingsReloadError object IndexSettingsReloadError { - final case class IndexLoadingSettingsError(underlying: LoadingSettingsError[IndexSettingsSource.LoadingError]) extends IndexSettingsReloadError - final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError + final case class IndexLoadingSettingsError(underlying: LoadingSettingsError[IndexSettingsSource.LoadingError]) + extends IndexSettingsReloadError + final case class ReloadError(underlying: RawSettingsReloadError) + extends IndexSettingsReloadError } sealed trait IndexSettingsUpdateError object IndexSettingsUpdateError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsUpdateError - case object TestSettingsNotSet extends IndexSettingsUpdateError - case object TestSettingsInvalidated extends IndexSettingsUpdateError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + extends IndexSettingsUpdateError + case object TestSettingsNotSet + extends IndexSettingsUpdateError + case object TestSettingsInvalidated + extends IndexSettingsUpdateError } sealed trait IndexSettingsInvalidationError object IndexSettingsInvalidationError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) extends IndexSettingsInvalidationError + final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + extends IndexSettingsInvalidationError } - private sealed trait ScheduledReloadError - private object ScheduledReloadError { + private [boot] sealed trait ScheduledReloadError + private [boot] object ScheduledReloadError { case object ReloadingInProgress extends ScheduledReloadError final case class EngineReloadError(underlying: IndexSettingsReloadError) extends ScheduledReloadError } @@ -341,31 +258,5 @@ object RorInstance { case object NoPeriodicIndexCheck extends Mode } - private sealed trait SettingsType - private object SettingsType { - case object Main extends SettingsType - case object Test extends SettingsType - - implicit val show: Show[SettingsType] = Show.show { - case Main => "main" - case Test => "test" - } - } - - private sealed trait ReloadTaskState - private object ReloadTaskState { - case object NotInitiated extends ReloadTaskState - final case class Running(cancelable: CancelableWithRequestId) extends ReloadTaskState - case object Stopped extends ReloadTaskState - } - - private final class CancelableWithRequestId(cancelable: Cancelable, requestId: RequestId) - extends Logging { - - def cancel(): Unit = { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check cancelled!") - cancelable.cancel() - } - } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala new file mode 100644 index 0000000000..3ab3e8df80 --- /dev/null +++ b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala @@ -0,0 +1,163 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.boot + +import cats.Show +import cats.implicits.toShow +import monix.eval.Task +import monix.execution.{Cancelable, Scheduler} +import org.apache.logging.log4j.scala.Logging +import tech.beshu.ror.SystemContext +import tech.beshu.ror.accesscontrol.domain.RequestId +import tech.beshu.ror.boot.RorInstance.ScheduledReloadError.{EngineReloadError, ReloadingInProgress} +import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsReloadError, ScheduledReloadError} +import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration +import tech.beshu.ror.implicits.* + +import java.util.concurrent.atomic.AtomicReference + +trait RorSettingsAutoReloader { + def start(): Unit + def stop(): Task[Unit] +} + +class EnabledRorSettingsAutoReloader(reloadInterval: PositiveFiniteDuration, + instance: RorInstance) + (implicit systemContext: SystemContext, + scheduler: Scheduler) + extends RorSettingsAutoReloader with Logging { + + private val reloadTaskState: AtomicReference[ReloadTaskState] = new AtomicReference(ReloadTaskState.NotInitiated) + + override def start(): Unit = { + logger.info(s"[CLUSTERWIDE SETTINGS] Auto reloading of ReadonlyREST in-index settings enabled") + scheduleEnginesReload(reloadInterval) + } + + override def stop(): Task[Unit] = { + for { + currentState <- Task.delay(reloadTaskState.getAndSet(ReloadTaskState.Stopped)) + _ <- Task.delay(currentState match { + case ReloadTaskState.NotInitiated => // do nothing + case ReloadTaskState.Running(cancelable) => cancelable.cancel() + case ReloadTaskState.Stopped => // do nothing + }) + } yield () + } + + private def scheduleEnginesReload(interval: PositiveFiniteDuration): Unit = { + val reloadTask = { (requestId: RequestId) => + Task.sequence { + Seq( + instance.tryMainEngineReload(requestId).map(result => (SettingsType.Main, result)), + instance.tryTestEngineReload(requestId).map(result => (SettingsType.Test, result)) + ) + } + } + scheduleNextIfNotStopping(interval, reloadTask) + } + + private def scheduleNextIfNotStopping(interval: PositiveFiniteDuration, + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]): Unit = { + implicit val requestId: RequestId = RequestId(systemContext.uuidProvider.random.toString) + val nextTask = scheduleIndexSettingsChecking(interval, reloadTask) + trySetNextReloadTask(nextTask) match { + case ReloadTaskState.NotInitiated => // nothing to do + case ReloadTaskState.Running(_) => // nothing to do + case ReloadTaskState.Stopped => nextTask.cancel() + } + } + + private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, + reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) + (implicit requestId: RequestId): CancelableWithRequestId = { + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check within ${interval.show}") + val cancellable = scheduler.scheduleOnce(interval.value) { + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") + reloadTask(requestId) + .runAsync { + case Right(reloadResults) => + reloadResults.foreach(logSettingsReloadResult) + scheduleNextIfNotStopping(interval, reloadTask) + case Left(ex) => + logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) + scheduleNextIfNotStopping(interval, reloadTask) + } + } + new CancelableWithRequestId(cancellable, requestId) + } + + private def trySetNextReloadTask(nextTask: CancelableWithRequestId) = { + reloadTaskState.updateAndGet { + case ReloadTaskState.NotInitiated | ReloadTaskState.Running(_) => + ReloadTaskState.Running(nextTask) + case ReloadTaskState.Stopped => + ReloadTaskState.Stopped + } + } + + private def logSettingsReloadResult(settingsReloadResult: (SettingsType, Either[ScheduledReloadError, Unit])) + (implicit requestId: RequestId): Unit = settingsReloadResult match { + case (_, Right(())) => + case (name, Left(ReloadingInProgress)) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Reloading of ${name.show} engine in progress ... skipping") + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.SettingsUpToDate(_))))) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ${name.show} settings are up to date. Nothing to reload.") + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.RorInstanceStopped)))) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Stopping periodic ${name.show} settings check - application is being stopped") + case (name, Left(EngineReloadError(IndexSettingsReloadError.ReloadError(RawSettingsReloadError.ReloadingFailed(startingFailure))))) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] ReadonlyREST ${name.show} engine starting failed: ${startingFailure.message.show}") + case (name, Left(EngineReloadError(IndexSettingsReloadError.IndexLoadingSettingsError(error)))) => + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ${name.show} settings from index failed: ${error.show}") + } + + private sealed trait SettingsType + private object SettingsType { + case object Main extends SettingsType + case object Test extends SettingsType + + implicit val show: Show[SettingsType] = Show.show { + case Main => "main" + case Test => "test" + } + } + + private sealed trait ReloadTaskState + private object ReloadTaskState { + case object NotInitiated extends ReloadTaskState + final case class Running(cancelable: CancelableWithRequestId) extends ReloadTaskState + case object Stopped extends ReloadTaskState + } + + private final class CancelableWithRequestId(cancelable: Cancelable, requestId: RequestId) + extends Logging { + + def cancel(): Unit = { + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check cancelled!") + cancelable.cancel() + } + } +} + +object DisabledRorSettingsAutoReloader extends RorSettingsAutoReloader with Logging { + + override def start(): Unit = { + logger.info(s"[CLUSTERWIDE SETTINGS] Auto reloading of ReadonlyREST in-index settings disabled") + } + + override def stop(): Task[Unit] = Task.unit +} \ No newline at end of file diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index e9a49a7ab4..6eea766349 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -57,10 +57,10 @@ class ConfigurableRetryStrategy(config: LoadingRetryStrategySettings) case Right(value) => Task.now(Right(value)) case Left(error) if shouldRetry(currentAttempt, maxAttempts) => - logger.debug(s"$operationDescription - retry attempt $currentAttempt/$maxAttempts failed with: ${error.show}. Retrying in ${config.attemptsInterval.show}...") + logger.debug(s"$operationDescription - retry attempt $currentAttempt/$maxAttempts failed. Retrying in ${config.attemptsInterval.show}...") attemptWithRetry(operation, currentAttempt + 1, maxAttempts, operationDescription) case Left(error) => - logger.debug(s"$operationDescription - failed after $currentAttempt attempts: ${error.show}") + logger.debug(s"$operationDescription - failed permanently after $currentAttempt attempts: ${error.show}") Task.now(Left(error)) } } yield finalResult diff --git a/es67x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es67x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 09112e0537..4749a51bfc 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -48,7 +48,6 @@ class RoleIndexSearcherWrapper(indexService: IndexService) extends IndexSearcher } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es70x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es70x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 09112e0537..4749a51bfc 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -48,7 +48,6 @@ class RoleIndexSearcherWrapper(indexService: IndexService) extends IndexSearcher } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es710x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es710x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es711x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es711x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es714x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es714x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es716x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es716x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es717x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es717x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es72x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es72x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 09112e0537..4749a51bfc 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -48,7 +48,6 @@ class RoleIndexSearcherWrapper(indexService: IndexService) extends IndexSearcher } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es73x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es73x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es74x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es74x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es77x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es77x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es78x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es78x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es79x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es79x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 5e42d55f7e..6121dabc12 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es80x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es80x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es810x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es810x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es811x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es811x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es812x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es812x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es813x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es813x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es814x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es814x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es815x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es815x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es816x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es816x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es818x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es818x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es81x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es81x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es82x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es82x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es83x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es83x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es84x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es84x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es85x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es85x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es87x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es87x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es88x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es88x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es89x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es89x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es90x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es90x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es91x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es91x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } From 6a85626636152c402d48c9cb87d3440e3ca65fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 9 Oct 2025 11:09:57 +0200 Subject: [PATCH 044/103] revert --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b8d54b676f..fcf605b707 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -870,6 +870,7 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + timeoutInMinutes: 180 - script: | set -e @@ -890,7 +891,6 @@ stages: echo "[RELEASE_ROR] executing ROR_TASK = $ROR_TASK" echo ">>> ($ROR_TASK) Releasing ROR" && ci/run-pipeline.sh - timeoutInMinutes: 360 env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) From b54d642c555c3cf4a6882a04866fe42f587baec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 9 Oct 2025 11:57:40 +0200 Subject: [PATCH 045/103] test fix --- .../tech/beshu/ror/boot/RorInstance.scala | 5 +- .../ror/boot/RorSettingsAutoReloader.scala | 6 +- .../elasticsearch.yml | 2 +- .../readonlyrest.yml | 9 -- .../IndexSettingsRelatedRorCoreTest.scala | 144 ++++++++++-------- .../unit/boot/ReadonlyRestStartingTests.scala | 51 ++----- .../es}/RorBootSettingsTest.scala | 4 +- .../es}/SslSettingsTest.scala | 14 +- .../YamlFileBasedRorSettingsLoaderTest.scala | 2 +- .../utils/WithReadonlyrestBootSupport.scala | 57 +++++++ 10 files changed, 170 insertions(+), 124 deletions(-) rename core/src/test/scala/tech/beshu/ror/unit/{configuration => settings/es}/RorBootSettingsTest.scala (99%) rename core/src/test/scala/tech/beshu/ror/unit/{configuration => settings/es}/SslSettingsTest.scala (96%) rename core/src/test/scala/tech/beshu/ror/unit/{configuration => settings/es}/YamlFileBasedRorSettingsLoaderTest.scala (98%) create mode 100644 core/src/test/scala/tech/beshu/ror/unit/utils/WithReadonlyrestBootSupport.scala diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index b3a99f4144..3af111ea37 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -38,6 +38,7 @@ import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration import java.time.Instant +import java.util.UUID class RorInstance private(boot: ReadonlyRest, mode: RorInstance.Mode, @@ -77,7 +78,9 @@ class RorInstance private(boot: ReadonlyRest, private val authMockRestApi = new AuthMockApi(rorInstance = this) settingsAutoReloader.start() - logger.info("ReadonlyREST was loaded!") + + val id: String = UUID.randomUUID().toString + logger.info(s"[$id] ReadonlyREST was loaded!") def engines: Option[Engines] = theMainSettingsEngine.engine.map(Engines(_, theTestSettingsEngine.engine)) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala index 3ab3e8df80..3bdef92e9d 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala @@ -85,16 +85,16 @@ class EnabledRorSettingsAutoReloader(reloadInterval: PositiveFiniteDuration, private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) (implicit requestId: RequestId): CancelableWithRequestId = { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check within ${interval.show}") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Scheduling next in-index settings check within ${interval.show}") val cancellable = scheduler.scheduleOnce(interval.value) { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Loading ReadonlyREST settings from index ...") reloadTask(requestId) .runAsync { case Right(reloadResults) => reloadResults.foreach(logSettingsReloadResult) scheduleNextIfNotStopping(interval, reloadTask) case Left(ex) => - logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) + logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Checking index settings failed: error", ex) scheduleNextIfNotStopping(interval, reloadTask) } } diff --git a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/elasticsearch.yml b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/elasticsearch.yml index 62e18f4e9c..66ad8fd762 100644 --- a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/elasticsearch.yml +++ b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/elasticsearch.yml @@ -5,7 +5,7 @@ xpack.security.enabled: true readonlyrest: force_load_from_file: true ssl_internode: - enable: false + enable: true keystore_file: "ror-keystore.jks" keystore_pass: readonlyrest1 key_pass: readonlyrest2 \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml index 3aeb9c309d..6e056f806f 100644 --- a/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml +++ b/core/src/test/resources/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/readonlyrest.yml @@ -1,14 +1,5 @@ readonlyrest: - ssl_internode: - enable: true - keystore_file: "ror-keystore.jks" - keystore_pass: readonlyrest1 - key_pass: readonlyrest2 - truststore_file: "ror-truststore.jks" - truststore_pass: readonlyrest3 - certificate_verification: true - access_control_rules: - name: "ADMIN" auth_key: admin:admin \ No newline at end of file diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala index 8bbd1e05bd..3c4442886f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala @@ -34,13 +34,14 @@ import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext import tech.beshu.ror.accesscontrol.audit.sink.AuditSinkServiceCreator import tech.beshu.ror.accesscontrol.domain.{IndexName, RequestId, RorSettingsFile} import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} +import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.RorInstance.TestSettings -import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} import tech.beshu.ror.es.{EsEnv, IndexDocumentManager} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.syntax.* +import tech.beshu.ror.unit.utils.WithReadonlyrestBootSupport import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsUtils.* @@ -49,6 +50,7 @@ import scala.concurrent.duration.* import scala.language.postfixOps class IndexSettingsRelatedRorCoreTest extends AnyWordSpec + with WithReadonlyrestBootSupport with Inside with OptionValues with EitherValues with MockFactory with Eventually { @@ -61,7 +63,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec "A ReadonlyREST core" should { "load ROR index name" when { "no index is defined in settings" should { - "start ROR with default index name" in { + "start ROR with default index name" in withReadonlyRest { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) @@ -69,13 +71,14 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) - .runSyncUnsafe() - - result shouldBe a[Right[_, RorInstance]] + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/") + ) + } { _ => + // nothing - just should start } - "save ROR settings in default index" in { + "save ROR settings in default index" in withReadonlyRestExt { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) @@ -83,24 +86,24 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) - .runSyncUnsafe() - - result shouldBe a[Right[_, RorInstance]] + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/"), + (indexDocumentManager, coreFactory) + ) + } { case (rorInstance, (indexDocumentManager, coreFactory)) => - mockCoreFactory(coreFactory, rorSettings) - mockInIndexMainSettingsSaving(indexDocumentManager, defaultRorIndexName) + mockCoreFactory(coreFactory, updatedRorSettings) + mockInIndexMainSettingsSaving(indexDocumentManager, defaultRorIndexName, updatedRorSettings) - val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadAndSave(rorSettings)(newRequestId()) + .forceReloadAndSave(updatedRorSettings)(newRequestId()) .runSyncUnsafe() forceReloadingResult should be(Right(())) } - "save ROR test settings in default index" in { + "save ROR test settings in default index" in withReadonlyRestExt { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, defaultRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, defaultRorIndexName) @@ -108,26 +111,26 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/")) - .runSyncUnsafe() - - result shouldBe a[Right[_, RorInstance]] + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/"), + (indexDocumentManager, coreFactory) + ) + } { case (rorInstance, (indexDocumentManager, coreFactory)) => - mockCoreFactory(coreFactory, rorSettings) - mockInIndexTestSettingsSaving(indexDocumentManager, defaultRorIndexName) + mockCoreFactory(coreFactory, updatedRorSettings) + mockInIndexTestSettingsSaving(indexDocumentManager, defaultRorIndexName, updatedRorSettings) - val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestSettingsEngine(rorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(updatedRorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() forceReloadingResult.value shouldBe a[TestSettings.Present] } } "custom index is defined in settings" should { - "start ROR with custom index name" in { + "start ROR with custom index name" in withReadonlyRest { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) @@ -135,12 +138,14 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) - .runSyncUnsafe() - result shouldBe a[Right[_, RorInstance]] + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/") + ) + } { _ => + // nothing - just should start } - "save ROR settings in custom index" in { + "save ROR settings in custom index" in withReadonlyRestExt { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) @@ -148,22 +153,24 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) - .runSyncUnsafe() + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/"), + (indexDocumentManager, coreFactory) + ) + } { case (rorInstance, (indexDocumentManager, coreFactory)) => - mockCoreFactory(coreFactory, rorSettings) - mockInIndexMainSettingsSaving(indexDocumentManager, customRorIndexName) + mockCoreFactory(coreFactory, updatedRorSettings) + mockInIndexMainSettingsSaving(indexDocumentManager, customRorIndexName, updatedRorSettings) - val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadAndSave(rorSettings)(newRequestId()) + .forceReloadAndSave(updatedRorSettings)(newRequestId()) .runSyncUnsafe() forceReloadingResult should be(Right(())) } - "save ROR test settings in custom index" in { + "save ROR test settings in custom index" in withReadonlyRestExt { val indexDocumentManager = mock[IndexDocumentManager] mockInIndexMainSettingsLoading(indexDocumentManager, customRorIndexName) mockInIndexTestSettingsLoading(indexDocumentManager, customRorIndexName) @@ -171,17 +178,19 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec val coreFactory = mock[CoreFactory] mockCoreFactory(coreFactory, indexRorSettings) - val result = readonlyRestBoot(coreFactory, indexDocumentManager) - .start(createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/")) - .runSyncUnsafe() + ( + createReadonlyRestBoot(coreFactory, indexDocumentManager), + createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/"), + (indexDocumentManager, coreFactory) + ) + } { case (rorInstance, (indexDocumentManager, coreFactory)) => - mockCoreFactory(coreFactory, rorSettings) - mockInIndexTestSettingsSaving(indexDocumentManager, customRorIndexName) + mockCoreFactory(coreFactory, updatedRorSettings) + mockInIndexTestSettingsSaving(indexDocumentManager, customRorIndexName, updatedRorSettings) - val rorInstance = result.value val forceReloadingResult = rorInstance - .forceReloadTestSettingsEngine(rorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) + .forceReloadTestSettingsEngine(updatedRorSettings, (5 minutes).toRefinedPositiveUnsafe)(newRequestId()) .runSyncUnsafe() forceReloadingResult.value shouldBe a[TestSettings.Present] @@ -190,8 +199,8 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec } } - private def readonlyRestBoot(factory: CoreFactory, - indexDocumentManager: IndexDocumentManager) = { + private def createReadonlyRestBoot(factory: CoreFactory, + indexDocumentManager: IndexDocumentManager) = { implicit val systemContext: SystemContext = SystemContext.default ReadonlyRest.create(factory, indexDocumentManager, mock[AuditSinkServiceCreator]) } @@ -224,22 +233,24 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec } private def mockInIndexMainSettingsSaving(indexDocumentManager: IndexDocumentManager, - indexName: NonEmptyString) = { + indexName: NonEmptyString, + rawRorSettings: RawRorSettings) = { (indexDocumentManager.saveDocumentJson _) - .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId, circeJsonFrom(s"""{ "settings": "${escapeJava(rorSettings.rawYaml)}"}""")) + .expects(fullIndexName(indexName), mainInIndexRorSettingsDocumentId, circeJsonFrom(s"""{ "settings": "${escapeJava(rawRorSettings.rawYaml)}"}""")) .once() .returns(Task.now(Right(()))) } private def mockInIndexTestSettingsSaving(indexDocumentManager: IndexDocumentManager, - indexName: NonEmptyString) = { + indexName: NonEmptyString, + rawRorSettings: RawRorSettings) = { (indexDocumentManager.saveDocumentJson _) .expects( where { (index: IndexName.Full, id: String, document: Json) => index == fullIndexName(indexName) && id == testInIndexRorSettingsDocumentId && - document.hcursor.get[String]("settings").toOption.contains(rorSettings.rawYaml) && + document.hcursor.get[String]("settings").toOption.contains(rawRorSettings.rawYaml) && document.hcursor.get[String]("expiration_ttl_millis").toOption.contains("300000") && document.hcursor.downField("expiration_timestamp").succeeded && document.hcursor.downField("auth_services_mocks").succeeded @@ -278,39 +289,42 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec private def newRequestId() = RequestId(UUID.randomUUID().toString) - private def createEsConfigBasedRorSettings(resourceEsConfigDir: String) = { + private def createEsConfigBasedRorSettings(resourceEsConfigDir: String): EsConfigBasedRorSettings = { implicit val systemContext: SystemContext = SystemContext.default val esConfig = File(getResourcePath(resourceEsConfigDir)) val esEnv = EsEnv(esConfig, esConfig, defaultEsVersionForTests, testEsNodeSettings) EsConfigBasedRorSettings.from(esEnv).runSyncUnsafe() match { - case Right(settings) => settings.copy(settingsFile = RorSettingsFile(esConfig / "readonlyrest.yml")) - case Left(error) => throw new IllegalStateException(s"Cannot create EsConfigBasedRorSettings: ${error.show}") + case Right(settings) => + val rorSettingsSourcesConfig = settings.settingsSource.copy(settingsFile = RorSettingsFile(esConfig / "readonlyrest.yml")) + settings.copy(settingsSource = rorSettingsSourcesConfig) + case Left(error) => + throw new IllegalStateException(s"Cannot create EsConfigBasedRorSettings: ${error.show}") } } - private lazy val rorSettings = rorSettingsFromUnsafe( + private lazy val indexRorSettings = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: - | | - name: test_block | type: allow | auth_key: admin:container - | - | - name: test_block_2 - | type: allow - | auth_key: dev:container - | |""".stripMargin ) - private lazy val indexRorSettings = rorSettingsFromUnsafe( + private lazy val updatedRorSettings = rorSettingsFromUnsafe( """ |readonlyrest: | access_control_rules: + | | - name: test_block | type: allow | auth_key: admin:container + | + | - name: test_block_2 + | type: allow + | auth_key: dev:container + | |""".stripMargin ) diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 90bb2ab2a5..1206a0bf9a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -18,7 +18,6 @@ package tech.beshu.ror.unit.boot import better.files.File import cats.data.NonEmptyList -import cats.effect.Resource import cats.implicits.* import eu.timepit.refined.types.string.NonEmptyString import io.circe.Json @@ -61,6 +60,7 @@ import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError import tech.beshu.ror.syntax.* +import tech.beshu.ror.unit.utils.WithReadonlyrestBootSupport import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.* @@ -73,6 +73,7 @@ import tech.beshu.ror.utils.misc.ScalaUtils.StringOps class ReadonlyRestStartingTests extends AnyWordSpec + with WithReadonlyrestBootSupport with Inside with OptionValues with EitherValues with MockFactory with Eventually { @@ -384,19 +385,25 @@ class ReadonlyRestStartingTests implicit val systemContext: SystemContext = createSystemContext() val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") - result should be (Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) + inside(result) { + case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + } } "ROR SSL (in readonlyrest.yml) is tried to be used when XPack Security is enabled" in { implicit val systemContext: SystemContext = createSystemContext() val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - result should be (Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) + inside(result) { + case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + } } "ROR FIPS SSL is tried to be used when XPack Security is enabled" in { implicit val systemContext: SystemContext = createSystemContext() val result = createEsConfigBasedRorSettings("/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") - result should be(Left(LoadingError.CannotUseRorSslWhenXPackSecurityIsEnabled)) + inside(result) { + case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + } } } } @@ -1358,9 +1365,10 @@ class ReadonlyRestStartingTests implicit val systemContext: SystemContext = createSystemContext() val readonlyRest = readonlyRestBoot(mock[CoreFactory], mock[IndexDocumentManager]) - val esConfigBasedRorSettings = - forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading/") - .copy(settingsMaxSize = Bytes(1)) + val esConfigBasedRorSettings = { + val settings = forceCreateEsConfigBasedRorSettings("/boot_tests/forced_file_loading/") + settings.copy(settingsSource = settings.settingsSource.copy(settingsMaxSize = Bytes(1))) + } val result = readonlyRest.start(esConfigBasedRorSettings).runSyncUnsafe() inside(result) { @@ -1421,34 +1429,6 @@ class ReadonlyRestStartingTests } } - private def withReadonlyRest(readonlyRestAndSettings: (ReadonlyRest, EsConfigBasedRorSettings)) - (testCode: RorInstance => Any): Unit = { - val (readonlyRest, esConfigBasedRorSettings) = readonlyRestAndSettings - withReadonlyRestExt((readonlyRest, esConfigBasedRorSettings, ())) { case (rorInstance, ()) => testCode(rorInstance) } - } - - private def withReadonlyRestExt[EXT](readonlyRestAndSettingsAndExt: (ReadonlyRest, EsConfigBasedRorSettings, EXT)) - (testCode: (RorInstance, EXT) => Any): Unit = { - val (readonlyRest, esConfigBasedRorSettings, ext) = readonlyRestAndSettingsAndExt - Resource - .make( - acquire = readonlyRest - .start(esConfigBasedRorSettings) - .flatMap { - case Right(startedInstance) => Task.now(startedInstance) - case Left(startingFailure) => Task.raiseError(new Exception(s"$startingFailure")) - } - )( - release = _.stop() - ) - .use { startedInstance => - Task.delay { - testCode(startedInstance, ext) - } - } - .runSyncUnsafe() - } - private def forceCreateEsConfigBasedRorSettings(resourceEsConfigDir: String) (implicit systemContext: SystemContext) = { createEsConfigBasedRorSettings(resourceEsConfigDir) match { @@ -1464,7 +1444,6 @@ class ReadonlyRestStartingTests EsConfigBasedRorSettings .from(esEnv) .runSyncUnsafe() - .map(settings => settings.copy(settingsFile = RorSettingsFile(esConfig / "readonlyrest.yml"))) } private def createSystemContext(refreshInterval: Option[FiniteDuration] = None, diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala similarity index 99% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala index 25da027391..2a561cc7d1 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala @@ -14,16 +14,16 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.unit.configuration +package tech.beshu.ror.unit.settings.es import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext +import tech.beshu.ror.es.EsEnv import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.settings.es.{MalformedSettings, RorBootSettings} -import tech.beshu.ror.es.EsEnv import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath, testEsNodeSettings} class RorBootSettingsTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala similarity index 96% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala index 147c3cbdad..adf2646dbf 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/SslSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala @@ -14,19 +14,21 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.unit.configuration +package tech.beshu.ror.unit.settings.es +import better.files.File import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile +import tech.beshu.ror.es.EsEnv import tech.beshu.ror.settings.es.SslSettings.* import tech.beshu.ror.settings.es.SslSettings.ServerCertificateSettings.{FileBasedSettings, KeystoreBasedSettings} import tech.beshu.ror.settings.es.{MalformedSettings, RorSslSettings} import tech.beshu.ror.utils.TestsPropertiesProvider -import tech.beshu.ror.utils.TestsUtils.getResourcePath +import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath, testEsNodeSettings} class SslSettingsTest extends AnyWordSpec with Inside { @@ -216,11 +218,11 @@ class SslSettingsTest } private def loadRorSslSettings(settingsFolderPath: String) = { + val esConfigFile = File(getResourcePath(settingsFolderPath)) + val rorSettingsFile = RorSettingsFile(getResourcePath(s"$settingsFolderPath/readonlyrest.yml")) + val esEnv = EsEnv(esConfigFile, esConfigFile, defaultEsVersionForTests, testEsNodeSettings) RorSslSettings - .load( - getResourcePath(s"$settingsFolderPath/elasticsearch.yml"), - RorSettingsFile(getResourcePath(s"$settingsFolderPath/readonlyrest.yml")), - ) + .load(esEnv, rorSettingsFile) .runSyncUnsafe() } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala similarity index 98% rename from core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala index 73189263da..47eff45b1d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/configuration/YamlFileBasedRorSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.unit.configuration +package tech.beshu.ror.unit.settings.es import better.files.File import cats.implicits.* diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/WithReadonlyrestBootSupport.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/WithReadonlyrestBootSupport.scala new file mode 100644 index 0000000000..6e9b371c42 --- /dev/null +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/WithReadonlyrestBootSupport.scala @@ -0,0 +1,57 @@ +/* + * This file is part of ReadonlyREST. + * + * ReadonlyREST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ReadonlyREST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ + */ +package tech.beshu.ror.unit.utils + +import cats.effect.Resource +import monix.eval.Task +import monix.execution.Scheduler.Implicits.global +import org.scalatest.Suite +import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings + +trait WithReadonlyrestBootSupport { + this: Suite => + + protected def withReadonlyRest(readonlyRestAndSettings: (ReadonlyRest, EsConfigBasedRorSettings)) + (testCode: RorInstance => Any): Unit = { + val (readonlyRest, esConfigBasedRorSettings) = readonlyRestAndSettings + withReadonlyRestExt((readonlyRest, esConfigBasedRorSettings, ())) { case (rorInstance, ()) => testCode(rorInstance) } + } + + protected def withReadonlyRestExt[EXT](readonlyRestAndSettingsAndExt: (ReadonlyRest, EsConfigBasedRorSettings, EXT)) + (testCode: (RorInstance, EXT) => Any): Unit = { + val (readonlyRest, esConfigBasedRorSettings, ext) = readonlyRestAndSettingsAndExt + Resource + .make( + acquire = readonlyRest + .start(esConfigBasedRorSettings) + .flatMap { + case Right(startedInstance) => Task.now(startedInstance) + case Left(startingFailure) => Task.raiseError(new Exception(s"$startingFailure")) + } + )( + release = _.stop() + ) + .use { startedInstance => + Task.delay { + testCode(startedInstance, ext) + } + } + .runSyncUnsafe() + } + +} From 6658deefe57d2d254ad9df75a80f6ab2c88ba1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 9 Oct 2025 15:53:52 +0200 Subject: [PATCH 046/103] test fix --- .../beshu/ror/unit/boot/ReadonlyRestStartingTests.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 1206a0bf9a..a5ade1eae6 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -47,15 +47,15 @@ import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreC import tech.beshu.ror.accesscontrol.factory.RorDependencies.NoOpImpersonationWarningsReader import tech.beshu.ror.accesscontrol.factory.{Core, CoreFactory, RorDependencies} import tech.beshu.ror.accesscontrol.logging.AccessControlListLoggingDecorator +import tech.beshu.ror.boot.ReadonlyRest import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorInstance.{IndexSettingsInvalidationError, TestSettings} -import tech.beshu.ror.boot.{ReadonlyRest, RorInstance} -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.DataStreamService.CreationResult.{Acknowledged, NotAcknowledged} import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentManager} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError @@ -64,12 +64,12 @@ import tech.beshu.ror.unit.utils.WithReadonlyrestBootSupport import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.* +import tech.beshu.ror.utils.misc.ScalaUtils.StringOps import java.time.Clock import java.util.UUID import scala.concurrent.duration.* import scala.language.postfixOps -import tech.beshu.ror.utils.misc.ScalaUtils.StringOps class ReadonlyRestStartingTests extends AnyWordSpec From 3431a06f0121e36cf34015b4f73b4f4056319371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 10 Oct 2025 10:12:41 +0200 Subject: [PATCH 047/103] fix --- .../tech/beshu/ror/boot/RorInstance.scala | 12 +++---- .../SettingsRelatedCreatorsAndLoaders.scala | 6 ++-- .../main/scala/tech/beshu/ror/implicits.scala | 4 +-- .../es/EsConfigBasedRorSettings.scala | 36 +++++-------------- ...a => LoadingRorCoreStrategySettings.scala} | 22 ++++++------ .../beshu/ror/settings/es/RorProperties.scala | 4 +-- .../ror/settings/es/RorSslSettings.scala | 2 +- .../es/YamlFileBasedSettingsLoader.scala | 12 ++++--- .../settings/ror/loader/RetryStrategy.scala | 2 +- .../settings/es/RorBootSettingsTest.scala | 10 +++--- ...ngsTest.scala => RorSslSettingsTest.scala} | 15 ++++---- ... => YamlFileBasedSettingsLoaderTest.scala} | 2 +- 12 files changed, 56 insertions(+), 71 deletions(-) rename core/src/main/scala/tech/beshu/ror/settings/es/{LoadingRorCoreStrategy.scala => LoadingRorCoreStrategySettings.scala} (83%) rename core/src/test/scala/tech/beshu/ror/unit/settings/es/{SslSettingsTest.scala => RorSslSettingsTest.scala} (95%) rename core/src/test/scala/tech/beshu/ror/unit/settings/es/{YamlFileBasedRorSettingsLoaderTest.scala => YamlFileBasedSettingsLoaderTest.scala} (96%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 3af111ea37..0755d7f5e7 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -29,8 +29,8 @@ import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings -import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategy} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategySettings} import tech.beshu.ror.settings.ror.source.IndexSettingsSource import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError @@ -188,13 +188,13 @@ object RorInstance { ) } - private def modeFrom(strategy: LoadingRorCoreStrategy) = { + private def modeFrom(strategy: LoadingRorCoreStrategySettings) = { strategy match { - case LoadingRorCoreStrategy.ForceLoadingFromFile => + case LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => + case LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Enabled(refreshInterval)) => + case LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Enabled(refreshInterval)) => Mode.WithPeriodicIndexCheck(refreshInterval) } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index 8e3309b15c..7c1cb23a30 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.boot import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategy} +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategySettings} import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser import tech.beshu.ror.settings.ror.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} import tech.beshu.ror.settings.ror.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} @@ -39,9 +39,9 @@ object SettingsRelatedCreatorsAndLoaders { val mainSettingsFileSource = MainSettingsFileSource.create(settingsFile, settingsYamlParser) val testSettingsIndexSource = TestSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { - case s@LoadingRorCoreStrategy.ForceLoadingFromFile => + case s@LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) - case s@LoadingRorCoreStrategy.LoadFromIndexWithFileFallback(retryStrategySettings, _) => + case s@LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(retryStrategySettings, _) => new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader( mainSettingsIndexSource, new ConfigurableRetryStrategy(retryStrategySettings), diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 0d53404bbd..c06239c6f6 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -61,8 +61,8 @@ import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index a366cace1d..cd9611f063 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -20,7 +20,6 @@ import better.files.File import cats.data.EitherT import monix.eval.Task import tech.beshu.ror.SystemContext -import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.es.EsEnv import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError.{FileNotFound, MalformedContent} @@ -29,7 +28,7 @@ import scala.language.{implicitConversions, postfixOps} final case class EsConfigBasedRorSettings(settingsSource: RorSettingsSourcesConfig, boot: RorBootSettings, ssl: Option[RorSslSettings], - loadingRorCoreStrategy: LoadingRorCoreStrategy) + loadingRorCoreStrategy: LoadingRorCoreStrategySettings) object EsConfigBasedRorSettings { @@ -44,36 +43,17 @@ object EsConfigBasedRorSettings { val esConfig = esEnv.elasticsearchConfig val result = for { _ <- EitherT.fromEither[Task](Either.cond(esConfig.file.exists, (), FileNotFound(esConfig.file): LoadingError)) - settingsSource <- loadSettingsSource(esEnv) - bootSettings <- loadRorBootSettings(esEnv) - sslSettings <- loadSslSettings(esEnv, settingsSource.settingsFile) - loadingRorCoreStrategy <- loadLoadingRorCoreStrategy(esEnv) + settingsSource <- RorSettingsSourcesConfig.from(esEnv).adaptError + bootSettings <- RorBootSettings.load(esEnv).adaptError + sslSettings <- RorSslSettings.load(esEnv, settingsSource.settingsFile).adaptError + loadingRorCoreStrategy <- LoadingRorCoreStrategySettings.load(esEnv).adaptError } yield EsConfigBasedRorSettings(settingsSource, bootSettings, sslSettings, loadingRorCoreStrategy) result.value } - private def loadRorBootSettings(esEnv: EsEnv) - (implicit systemContext: SystemContext): EitherT[Task, LoadingError, RorBootSettings] = { - EitherT(RorBootSettings.load(esEnv)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) - } - - private def loadLoadingRorCoreStrategy(esEnv: EsEnv) - (implicit systemContext: SystemContext): EitherT[Task, LoadingError, LoadingRorCoreStrategy] = { - EitherT(LoadingRorCoreStrategy.load(esEnv)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) - } - - private def loadSettingsSource(esEnv: EsEnv) - (implicit systemContext: SystemContext): EitherT[Task, LoadingError, RorSettingsSourcesConfig] = { - EitherT(RorSettingsSourcesConfig.from(esEnv)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) - } - - private def loadSslSettings(esEnv: EsEnv, rorSettingsFile: RorSettingsFile) - (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { - EitherT(RorSslSettings.load(esEnv, rorSettingsFile)) - .leftMap(error => MalformedContent(esEnv.elasticsearchConfig.file, error.message)) + private implicit class AdaptError[T](val task: Task[Either[MalformedSettings, T]]) extends AnyVal { + def adaptError: EitherT[Task, LoadingError, T] = + EitherT(task).leftMap(error => MalformedContent(error.file, error.message): LoadingError) } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala similarity index 83% rename from core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala index 03798a791e..76a15b8358 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala @@ -24,20 +24,20 @@ import monix.eval.Task import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.concurrent.duration.{DurationInt, FiniteDuration} import scala.language.{implicitConversions, postfixOps} -sealed trait LoadingRorCoreStrategy -object LoadingRorCoreStrategy extends YamlFileBasedSettingsLoaderSupport { +sealed trait LoadingRorCoreStrategySettings +object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport { - case object ForceLoadingFromFile extends LoadingRorCoreStrategy + case object ForceLoadingFromFile$Settings extends LoadingRorCoreStrategySettings final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, coreRefreshSettings: CoreRefreshSettings) - extends LoadingRorCoreStrategy + extends LoadingRorCoreStrategySettings final case class LoadingRetryStrategySettings(attemptsInterval: LoadingAttemptsInterval, attemptsCount: LoadingAttemptsCount, @@ -71,25 +71,25 @@ object LoadingRorCoreStrategy extends YamlFileBasedSettingsLoaderSupport { } def load(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, LoadingRorCoreStrategy]] = { - implicit val decoder: Decoder[LoadingRorCoreStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) - loadSetting[LoadingRorCoreStrategy](esEnv, "ROR loading core strategy settings") + (implicit systemContext: SystemContext): Task[Either[MalformedSettings, LoadingRorCoreStrategySettings]] = { + implicit val decoder: Decoder[LoadingRorCoreStrategySettings] = decoders.loadRorCoreStrategyDecoder(esEnv) + loadSetting[LoadingRorCoreStrategySettings](esEnv, "ROR loading core strategy settings") } private object decoders { implicit def loadRorCoreStrategyDecoder(esEnv: EsEnv) - (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategy] = { + (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategySettings] = { YamlKeyDecoder[Boolean]( path = NonEmptyList.of("readonlyrest", "force_load_from_file"), default = false ) flatMap { case true => - Decoder.const(LoadingRorCoreStrategy.ForceLoadingFromFile) + Decoder.const(LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings) case false => for { loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) coreRefreshIntervalSettings <- loadCoreRefreshSettings(systemContext.propertiesProvider) - } yield LoadingRorCoreStrategy.LoadFromIndexWithFileFallback( + } yield LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback( loadingRetryStrategySettings, coreRefreshIntervalSettings ) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala index 29bf52248a..f07d3f3276 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala @@ -27,8 +27,8 @@ import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.providers.PropertiesProvider.PropName -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.CoreRefreshSettings -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.RefinedUtils.* diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index de1d44325e..3f1ae463b4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -92,7 +92,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { } .subflatMap { case Some(ssl) if xpackSecuritySettings.enabled => - Left(MalformedSettings("Cannot use ROR SSL when XPack Security is enabled")) + Left(MalformedSettings(esConfigFile.file, "Cannot use ROR SSL when XPack Security is enabled")) case rorSsl@(Some(_) | None) => Right(rorSsl) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala index b376269fc4..2cb7c924fd 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala @@ -42,7 +42,7 @@ final class YamlFileBasedSettingsLoader(file: File) .flatMap { json => implicitly[Decoder[SETTINGS]] .decodeJson(json) - .left.map(e => MalformedSettings(s"Cannot load ${settingsName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) + .left.map(e => createError(s"Cannot load ${settingsName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) } } @@ -50,11 +50,11 @@ final class YamlFileBasedSettingsLoader(file: File) file.fileReader { reader => yamlParser .parse(reader) - .left.map(e => MalformedSettings(s"Cannot parse file ${file.pathAsString.show} content. Cause: ${e.message.show}")) + .left.map(e => createError(s"Cannot parse file ${file.pathAsString.show} content. Cause: ${e.message.show}")) .flatMap { json => jsonStaticVariableResolver .resolve(json) - .left.map(e => MalformedSettings(s"Unable to resolve environment variables for file ${file.pathAsString.show}. $e.")) + .left.map(e => createError(s"Unable to resolve environment variables for file ${file.pathAsString.show}. $e.")) } .map(jsonWithOneLinerKeysToRegularJson) } @@ -66,9 +66,11 @@ final class YamlFileBasedSettingsLoader(file: File) case other => other } } + + private def createError(message:String) = MalformedSettings(file, message) } -final case class MalformedSettings(message: String) +final case class MalformedSettings(file: File, message: String) private[es] trait YamlFileBasedSettingsLoaderSupport { @@ -84,7 +86,7 @@ private[es] trait YamlFileBasedSettingsLoaderSupport { for { strategy <- loader .loadSettings[T](settingsName) - .left.map(error => MalformedSettings(error.message)) + .left.map(error => MalformedSettings(file, error.message)) } yield strategy } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index 6eea766349..b39472a053 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -22,7 +22,7 @@ import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.es.LoadingRorCoreStrategy.LoadingRetryStrategySettings +import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings trait RetryStrategy { def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala index 2a561cc7d1..42ae0e5384 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala @@ -76,22 +76,24 @@ class RorBootSettingsTest "not be able to load" when { "not started response code is malformed" in { val esConfigFolderPath = "/boot_tests/boot_config/not_started_code_malformed" - val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml") RorBootSettings.load(esEnvFrom(esConfigFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( - s"Cannot load ROR boot settings from file $expectedFilePath. " + + expectedFilePath, + s"Cannot load ROR boot settings from file ${expectedFilePath.toString}. " + s"Cause: Unsupported response code [200] for readonlyrest.not_started_response_code. Supported response codes are: 403, 503." ) } } "failed to start response code is malformed" in { val esConfigFolderPath = "/boot_tests/boot_config/failed_to_start_code_malformed" - val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml") RorBootSettings.load(esEnvFrom(esConfigFolderPath)).runSyncUnsafe() shouldBe Left { MalformedSettings( - s"Cannot load ROR boot settings from file $expectedFilePath. " + + expectedFilePath, + s"Cannot load ROR boot settings from file ${expectedFilePath.toString}. " + s"Cause: Unsupported response code [200] for readonlyrest.failed_to_start_response_code. Supported response codes are: 403, 503." ) } diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala similarity index 95% rename from core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala index adf2646dbf..d4594a8e6f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/SslSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala @@ -30,7 +30,7 @@ import tech.beshu.ror.settings.es.{MalformedSettings, RorSslSettings} import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath, testEsNodeSettings} -class SslSettingsTest +class RorSslSettingsTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = new SystemContext( @@ -113,9 +113,9 @@ class SslSettingsTest "SSL settings are malformed" when { "keystore_file entry is missing" in { val esConfigFolderPath = "/boot_tests/es_api_ssl_settings_malformed" - val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml").toString + val expectedFilePath = getResourcePath(s"$esConfigFolderPath/elasticsearch.yml") loadRorSslSettings(esConfigFolderPath) shouldBe Left { - MalformedSettings(s"Cannot load ROR SSL settings from file $expectedFilePath. Cause: Missing required field") + MalformedSettings(expectedFilePath, s"Cannot load ROR SSL settings from file ${expectedFilePath.toString}. Cause: Missing required field") } } } @@ -128,11 +128,12 @@ class SslSettingsTest } "SSL settings contain both pem and truststore based configuration" in { val configFolderPath = "/boot_tests/es_api_ssl_settings_both_pem_and_keystore_configured" - val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml").toString + val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml") loadRorSslSettings(configFolderPath) shouldBe Left { MalformedSettings( - s"Cannot load ROR SSL settings from file $expectedFilePath. " + + expectedFilePath, + s"Cannot load ROR SSL settings from file ${expectedFilePath.toString}. " + s"Cause: Field sets [server_certificate_key_file, server_certificate_file] and [keystore_file, keystore_pass, key_pass, key_alias] could not be present in the same settings section") } } @@ -203,9 +204,9 @@ class SslSettingsTest "SSL settings are malformed" when { "keystore_file entry is missing" in { val configFolderPath = "/boot_tests/internode_ssl_settings_malformed" - val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml").toString + val expectedFilePath = getResourcePath(s"$configFolderPath/elasticsearch.yml") loadRorSslSettings(configFolderPath) shouldBe Left { - MalformedSettings(s"Cannot load ROR SSL settings from file $expectedFilePath. Cause: Missing required field") + MalformedSettings(expectedFilePath, s"Cannot load ROR SSL settings from file ${expectedFilePath.toString}. Cause: Missing required field") } } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala similarity index 96% rename from core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala rename to core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala index 47eff45b1d..d1db30b907 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedRorSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala @@ -25,7 +25,7 @@ import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader -class YamlFileBasedRorSettingsLoaderTest extends AnyWordSpec with Inside { +class YamlFileBasedSettingsLoaderTest extends AnyWordSpec with Inside { private implicit val systemContext: SystemContext = new SystemContext( envVarsProvider = name => From ee5cb97dd3c513637b9a1cb5cb37a9ff6a0f60bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 10 Oct 2025 10:45:26 +0200 Subject: [PATCH 048/103] wip --- .../main/scala/tech/beshu/ror/implicits.scala | 10 +++---- .../es/EsConfigBasedRorSettings.scala | 25 ++++-------------- .../es/LoadingRorCoreStrategySettings.scala | 3 ++- .../ror/settings/es/RorBootSettings.scala | 3 ++- .../es/RorSettingsSourcesConfig.scala | 3 ++- .../ror/settings/es/RorSslSettings.scala | 13 +++++----- .../es/YamlFileBasedSettingsLoader.scala | 26 ++++++++++++------- .../unit/boot/ReadonlyRestStartingTests.scala | 10 +++---- .../settings/es/RorBootSettingsTest.scala | 3 ++- .../unit/settings/es/RorSslSettingsTest.scala | 6 +++-- .../es/YamlFileBasedSettingsLoaderTest.scala | 23 +++++++++++----- 11 files changed, 66 insertions(+), 59 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index c06239c6f6..0df845fdac 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -60,9 +60,9 @@ import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError @@ -422,10 +422,10 @@ trait LogsShowInstances implicit val mainRorSettingsShow: Show[MainRorSettings] = Show.show(_.rawSettings.rawYaml) - implicit val esConfigBasedRorSettingsLoadingErrorShow: Show[EsConfigBasedRorSettings.LoadingError] = Show.show { - case EsConfigBasedRorSettings.LoadingError.FileNotFound(file) => - s"Cannot find elasticsearch settings file: [${file.show}]" - case EsConfigBasedRorSettings.LoadingError.MalformedContent(file, message) => + implicit val esConfigBasedRorSettingsLoadingErrorShow: Show[YamlFileBasedSettingsLoader.LoadingError] = Show.show { + case YamlFileBasedSettingsLoader.LoadingError.FileNotFound(file) => + s"Cannot find settings file: [${file.show}]" + case YamlFileBasedSettingsLoader.LoadingError.MalformedSettings(file, message) => s"Settings file is malformed: [${file.show}], ${message.show}" } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index cd9611f063..d1a1621207 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -16,12 +16,11 @@ */ package tech.beshu.ror.settings.es -import better.files.File import cats.data.EitherT import monix.eval.Task import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError.{FileNotFound, MalformedContent} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import scala.language.{implicitConversions, postfixOps} @@ -32,28 +31,14 @@ final case class EsConfigBasedRorSettings(settingsSource: RorSettingsSourcesConf object EsConfigBasedRorSettings { - sealed trait LoadingError - object LoadingError { - final case class FileNotFound(file: File) extends LoadingError - final case class MalformedContent(file: File, message: String) extends LoadingError - } - def from(esEnv: EsEnv) (implicit systemContext: SystemContext): Task[Either[LoadingError, EsConfigBasedRorSettings]] = { - val esConfig = esEnv.elasticsearchConfig val result = for { - _ <- EitherT.fromEither[Task](Either.cond(esConfig.file.exists, (), FileNotFound(esConfig.file): LoadingError)) - settingsSource <- RorSettingsSourcesConfig.from(esEnv).adaptError - bootSettings <- RorBootSettings.load(esEnv).adaptError - sslSettings <- RorSslSettings.load(esEnv, settingsSource.settingsFile).adaptError - loadingRorCoreStrategy <- LoadingRorCoreStrategySettings.load(esEnv).adaptError + settingsSource <- EitherT(RorSettingsSourcesConfig.from(esEnv)) + bootSettings <- EitherT(RorBootSettings.load(esEnv)) + sslSettings <- EitherT(RorSslSettings.load(esEnv, settingsSource.settingsFile)) + loadingRorCoreStrategy <- EitherT(LoadingRorCoreStrategySettings.load(esEnv)) } yield EsConfigBasedRorSettings(settingsSource, bootSettings, sslSettings, loadingRorCoreStrategy) result.value } - - private implicit class AdaptError[T](val task: Task[Either[MalformedSettings, T]]) extends AnyVal { - def adaptError: EitherT[Task, LoadingError, T] = - EitherT(task).leftMap(error => MalformedContent(error.file, error.message): LoadingError) - } - } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala index 76a15b8358..59f6f4a038 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala @@ -25,6 +25,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} import tech.beshu.ror.utils.yaml.YamlKeyDecoder @@ -71,7 +72,7 @@ object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport } def load(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, LoadingRorCoreStrategySettings]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, LoadingRorCoreStrategySettings]] = { implicit val decoder: Decoder[LoadingRorCoreStrategySettings] = decoders.loadRorCoreStrategyDecoder(esEnv) loadSetting[LoadingRorCoreStrategySettings](esEnv, "ROR loading core strategy settings") } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala index 210a76624d..7f3f02adc4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorBootSettings.scala @@ -23,6 +23,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.yaml.YamlKeyDecoder final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, @@ -31,7 +32,7 @@ final case class RorBootSettings(rorNotStartedResponse: RorNotStartedResponse, object RorBootSettings extends YamlFileBasedSettingsLoaderSupport { def load(env: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorBootSettings]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, RorBootSettings]] = { implicit val rorBootSettingsDecoder: Decoder[RorBootSettings] = decoders.rorBootSettingsDecoder loadSetting[RorBootSettings](env, "ROR boot settings") } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala index 6bdffb838c..5352934d7d 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala @@ -25,6 +25,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.yaml.YamlKeyDecoder final case class RorSettingsSourcesConfig(settingsIndex: RorSettingsIndex, @@ -34,7 +35,7 @@ final case class RorSettingsSourcesConfig(settingsIndex: RorSettingsIndex, object RorSettingsSourcesConfig extends YamlFileBasedSettingsLoaderSupport { def from(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, RorSettingsSourcesConfig]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, RorSettingsSourcesConfig]] = { implicit val decoder: Decoder[RorSettingsSourcesConfig] = for { rorSettingsIndex <- decoders.rorSettingsIndexDecoder rorSettingsFile <- decoders.rorSettingsFileDecoder(esEnv) diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index 3f1ae463b4..86915d3817 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -27,6 +27,7 @@ import tech.beshu.ror.accesscontrol.utils.CirceOps.DecoderHelpers import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.SslSettings.* +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.yaml.YamlKeyDecoder @@ -62,7 +63,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { def load(esEnv: EsEnv, rorSettingsFile: RorSettingsFile) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, Option[RorSslSettings]]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, Option[RorSslSettings]]] = { val result = for { xpackSecuritySettings <- loadXpackSecuritySettings(esEnv) rorSslSettings <- loadRorSslSetting(esEnv.elasticsearchConfig, rorSettingsFile, xpackSecuritySettings) @@ -71,7 +72,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { } private def loadXpackSecuritySettings(esEnv: EsEnv) - (implicit systemContext: SystemContext): EitherT[Task, MalformedSettings, XpackSecuritySettings] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, XpackSecuritySettings] = { EitherT { implicit val decoder: Decoder[XpackSecuritySettings] = xpackSettingsDecoder(esEnv.isOssDistribution) loadSetting[XpackSecuritySettings](esEnv, "X-Pack settings") @@ -81,7 +82,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { private def loadRorSslSetting(esConfigFile: EsConfigFile, rorSettingsFile: RorSettingsFile, xpackSecuritySettings: XpackSecuritySettings) - (implicit systemContext: SystemContext): EitherT[Task, MalformedSettings, Option[RorSslSettings]] = { + (implicit systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { implicit val rorSslSettingsDecoder: Decoder[Option[RorSslSettings]] = SslDecoders.rorSslDecoder(esConfigFile.file.parent) loadSslSettingsFrom(esConfigFile.file) .flatMap { @@ -92,7 +93,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { } .subflatMap { case Some(ssl) if xpackSecuritySettings.enabled => - Left(MalformedSettings(esConfigFile.file, "Cannot use ROR SSL when XPack Security is enabled")) + Left(LoadingError.MalformedSettings(esConfigFile.file, "Cannot use ROR SSL when XPack Security is enabled"): LoadingError) case rorSsl@(Some(_) | None) => Right(rorSsl) } @@ -100,7 +101,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { private def fallbackToRorSettingsFile(rorSettingsFile: RorSettingsFile) (implicit decoder: Decoder[Option[RorSslSettings]], - systemContext: SystemContext): EitherT[Task, MalformedSettings, Option[RorSslSettings]] = { + systemContext: SystemContext): EitherT[Task, LoadingError, Option[RorSslSettings]] = { val settingsFile = rorSettingsFile.file if (settingsFile.exists) { for { @@ -148,7 +149,7 @@ object RorSslSettings extends YamlFileBasedSettingsLoaderSupport with Logging { } } - private def lift[T](value: => T): EitherT[Task, MalformedSettings, T] = EitherT.rightT(value) + private def lift[T](value: => T): EitherT[Task, LoadingError, T] = EitherT.rightT(value) } sealed trait SslSettings { diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala index 2cb7c924fd..cfbe5afdb7 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala @@ -24,6 +24,7 @@ import tech.beshu.ror.accesscontrol.blocks.variables.transformation.Transformati import tech.beshu.ror.accesscontrol.factory.JsonStaticVariablesResolver import tech.beshu.ror.es.EsEnv import tech.beshu.ror.implicits.* +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.yaml.YamlOps.jsonWithOneLinerKeysToRegularJson import tech.beshu.ror.utils.yaml.YamlParser @@ -37,7 +38,7 @@ final class YamlFileBasedSettingsLoader(file: File) TransformationCompiler.withoutAliases(systemContext.variablesFunctions) ) - def loadSettings[SETTINGS: Decoder](settingsName: String): Either[MalformedSettings, SETTINGS] = { + def loadSettings[SETTINGS: Decoder](settingsName: String): Either[LoadingError, SETTINGS] = { loadedSettingsJson .flatMap { json => implicitly[Decoder[SETTINGS]] @@ -46,7 +47,7 @@ final class YamlFileBasedSettingsLoader(file: File) } } - private lazy val loadedSettingsJson: Either[MalformedSettings, Json] = { + private lazy val loadedSettingsJson: Either[LoadingError, Json] = { file.fileReader { reader => yamlParser .parse(reader) @@ -67,26 +68,31 @@ final class YamlFileBasedSettingsLoader(file: File) } } - private def createError(message:String) = MalformedSettings(file, message) + private def createError(message:String) = LoadingError.MalformedSettings(file, message) } -final case class MalformedSettings(file: File, message: String) +object YamlFileBasedSettingsLoader { + sealed trait LoadingError + object LoadingError { + final case class FileNotFound(file: File) extends LoadingError + final case class MalformedSettings(file: File, message: String) extends LoadingError + } +} private[es] trait YamlFileBasedSettingsLoaderSupport { protected def loadSetting[T: Decoder](esEnv: EsEnv, settingsName: String) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, T]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, T]] = { loadSetting(esEnv.elasticsearchConfig.file, settingsName) } protected def loadSetting[T: Decoder](file: File, settingsName: String) - (implicit systemContext: SystemContext): Task[Either[MalformedSettings, T]] = { + (implicit systemContext: SystemContext): Task[Either[LoadingError, T]] = { Task.delay { - val loader = new YamlFileBasedSettingsLoader(file) for { - strategy <- loader - .loadSettings[T](settingsName) - .left.map(error => MalformedSettings(file, error.message)) + _ <- Either.cond(file.exists, (), LoadingError.FileNotFound(file): LoadingError) + loader = new YamlFileBasedSettingsLoader(file) + strategy <- loader.loadSettings[T](settingsName) } yield strategy } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index a5ade1eae6..c574032feb 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -55,7 +55,7 @@ import tech.beshu.ror.es.DataStreamService.{CreationResult, DataStreamSettings} import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.es.{DataStreamBasedAuditSinkService, DataStreamService, EsEnv, IndexDocumentManager} import tech.beshu.ror.settings.es.EsConfigBasedRorSettings -import tech.beshu.ror.settings.es.EsConfigBasedRorSettings.LoadingError +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError @@ -287,7 +287,7 @@ class ReadonlyRestStartingTests implicit val systemContext: SystemContext = createSystemContext() val result = createEsConfigBasedRorSettings(resourcesPath) - inside(result) { case Left(LoadingError.MalformedContent(_, message)) => + inside(result) { case Left(LoadingError.MalformedSettings(_, message)) => message should startWith("Cannot parse file") } } @@ -386,7 +386,7 @@ class ReadonlyRestStartingTests val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_es_file_xpack_security_enabled/") inside(result) { - case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + case Left(LoadingError.MalformedSettings(_, "Cannot use ROR SSL when XPack Security is enabled")) => } } "ROR SSL (in readonlyrest.yml) is tried to be used when XPack Security is enabled" in { @@ -394,7 +394,7 @@ class ReadonlyRestStartingTests val result = createEsConfigBasedRorSettings("/boot_tests/ror_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") inside(result) { - case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + case Left(LoadingError.MalformedSettings(_, "Cannot use ROR SSL when XPack Security is enabled")) => } } "ROR FIPS SSL is tried to be used when XPack Security is enabled" in { @@ -402,7 +402,7 @@ class ReadonlyRestStartingTests val result = createEsConfigBasedRorSettings("/boot_tests/ror_fisb_ssl_declared_in_readonlyrest_file_xpack_security_enabled/") inside(result) { - case Left(LoadingError.MalformedContent(_, "Cannot use ROR SSL when XPack Security is enabled")) => + case Left(LoadingError.MalformedSettings(_, "Cannot use ROR SSL when XPack Security is enabled")) => } } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala index 42ae0e5384..b1c3e75eb7 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorBootSettingsTest.scala @@ -22,8 +22,9 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.settings.es.RorBootSettings import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} -import tech.beshu.ror.settings.es.{MalformedSettings, RorBootSettings} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError.MalformedSettings import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath, testEsNodeSettings} class RorBootSettingsTest diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala index d4594a8e6f..79089e646a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala @@ -24,9 +24,11 @@ import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.settings.es.RorSslSettings import tech.beshu.ror.settings.es.SslSettings.* import tech.beshu.ror.settings.es.SslSettings.ServerCertificateSettings.{FileBasedSettings, KeystoreBasedSettings} -import tech.beshu.ror.settings.es.{MalformedSettings, RorSslSettings} +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError.MalformedSettings import tech.beshu.ror.utils.TestsPropertiesProvider import tech.beshu.ror.utils.TestsUtils.{defaultEsVersionForTests, getResourcePath, testEsNodeSettings} @@ -122,7 +124,7 @@ class RorSslSettingsTest "file content is not valid yaml" in { val error = loadRorSslSettings("/boot_tests/es_api_ssl_settings_file_invalid_yaml/") inside(error) { - case Left(error) => + case Left(error: LoadingError.MalformedSettings) => error.message should startWith("Cannot parse file") } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala index d1db30b907..27054fbfa2 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala @@ -24,6 +24,7 @@ import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.SystemContext import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader +import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError class YamlFileBasedSettingsLoaderTest extends AnyWordSpec with Inside { @@ -48,22 +49,30 @@ class YamlFileBasedSettingsLoaderTest extends AnyWordSpec with Inside { val result = loadFromTempFile[String](""""${USER_NAME}#{to_uppercase}"""") result shouldBe "JOHN".asRight } - "fail for non existing vairable" in { + "fail for non-existing variable" in { val result = loadFromTempFile[String](""""${WRONG_VARIABLE}"""") inside(result) { - case Left(error) => + case Left(error: LoadingError.MalformedSettings) => error.message should include("WRONG_VARIABLE") } } + "fail for non-existing file" in { + val loader = new YamlFileBasedSettingsLoader(File("non-existing-file")) + val result = loader.loadSettings[String]("TEST") + inside(result) { + case Left(error: LoadingError.FileNotFound) => + } + } } private def loadFromTempFile[A: Decoder](content: String) = - tempFile(content).map { file => - createFileConfigLoader(file) - .loadSettings[A]("TEST") - }.get() + tempFile(content) + .map { file => + val loader = new YamlFileBasedSettingsLoader(file) + loader.loadSettings[A]("TEST") + } + .get() private def tempFile(content: String) = File.temporaryFile().map(_.write(content)) - private def createFileConfigLoader(file: File) = new YamlFileBasedSettingsLoader(file) } From 5496593f9da9a203cf5330f5dc8082c55b2c1bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 10 Oct 2025 11:27:53 +0200 Subject: [PATCH 049/103] fix --- .../es/YamlFileBasedSettingsLoader.scala | 30 +++++++++---------- .../es/YamlFileBasedSettingsLoaderTest.scala | 5 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala index cfbe5afdb7..6916fde703 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/YamlFileBasedSettingsLoader.scala @@ -38,13 +38,16 @@ final class YamlFileBasedSettingsLoader(file: File) TransformationCompiler.withoutAliases(systemContext.variablesFunctions) ) - def loadSettings[SETTINGS: Decoder](settingsName: String): Either[LoadingError, SETTINGS] = { - loadedSettingsJson - .flatMap { json => - implicitly[Decoder[SETTINGS]] - .decodeJson(json) - .left.map(e => createError(s"Cannot load ${settingsName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) - } + def loadSettings[SETTINGS: Decoder](settingsName: String): Task[Either[LoadingError, SETTINGS]] = Task.delay { + for { + _ <- Either.cond(file.exists, (), LoadingError.FileNotFound(file): LoadingError) + settings <- loadedSettingsJson + .flatMap { json => + implicitly[Decoder[SETTINGS]] + .decodeJson(json) + .left.map(e => createError(s"Cannot load ${settingsName.show} from file ${file.pathAsString.show}. Cause: ${prettyCause(e).show}")) + } + } yield settings } private lazy val loadedSettingsJson: Either[LoadingError, Json] = { @@ -68,10 +71,10 @@ final class YamlFileBasedSettingsLoader(file: File) } } - private def createError(message:String) = LoadingError.MalformedSettings(file, message) + private def createError(message: String) = LoadingError.MalformedSettings(file, message) } -object YamlFileBasedSettingsLoader { +object YamlFileBasedSettingsLoader { sealed trait LoadingError object LoadingError { final case class FileNotFound(file: File) extends LoadingError @@ -88,13 +91,8 @@ private[es] trait YamlFileBasedSettingsLoaderSupport { protected def loadSetting[T: Decoder](file: File, settingsName: String) (implicit systemContext: SystemContext): Task[Either[LoadingError, T]] = { - Task.delay { - for { - _ <- Either.cond(file.exists, (), LoadingError.FileNotFound(file): LoadingError) - loader = new YamlFileBasedSettingsLoader(file) - strategy <- loader.loadSettings[T](settingsName) - } yield strategy - } + val loader = new YamlFileBasedSettingsLoader(file) + loader.loadSettings[T](settingsName) } } diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala index 27054fbfa2..85529a4cbc 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/YamlFileBasedSettingsLoaderTest.scala @@ -19,6 +19,7 @@ package tech.beshu.ror.unit.settings.es import better.files.File import cats.implicits.* import io.circe.Decoder +import monix.execution.Scheduler.Implicits.global import org.scalatest.Inside import org.scalatest.matchers.should.Matchers.* import org.scalatest.wordspec.AnyWordSpec @@ -58,7 +59,7 @@ class YamlFileBasedSettingsLoaderTest extends AnyWordSpec with Inside { } "fail for non-existing file" in { val loader = new YamlFileBasedSettingsLoader(File("non-existing-file")) - val result = loader.loadSettings[String]("TEST") + val result = loader.loadSettings[String]("TEST").runSyncUnsafe() inside(result) { case Left(error: LoadingError.FileNotFound) => } @@ -69,7 +70,7 @@ class YamlFileBasedSettingsLoaderTest extends AnyWordSpec with Inside { tempFile(content) .map { file => val loader = new YamlFileBasedSettingsLoader(file) - loader.loadSettings[A]("TEST") + loader.loadSettings[A]("TEST").runSyncUnsafe() } .get() From 33004df182efa274d81c7ba842296d40446154a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 16 Oct 2025 12:22:00 +0200 Subject: [PATCH 050/103] renaming --- .../rules/auth/RorKbnRulesDecoders.scala | 4 +- .../rules/kibana/KibanaRulesDecoders.scala | 4 +- .../es/RorSettingsSourcesConfig.scala | 2 +- ...ticationYamlLoadedAccessControlTests.scala | 4 +- ...AndAuthzYamlLoadedAccessControlTests.scala | 4 +- .../factory/ImpersonationWarningsTests.scala | 4 +- .../ror/unit/acl/factory/LocalUsersTest.scala | 16 +-- .../ImpersonationSettingsTests.scala | 4 +- .../LdapServicesSettingsTests.scala | 4 +- .../VariableTransformationAliasesTests.scala | 4 +- .../rules/auth/ApiKeysRuleSettingsTests.scala | 4 +- ...BKDF2WithHmacSHA512RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha1RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha256RuleSettingsTests.scala | 4 +- .../auth/AuthKeySha512RuleSettingsTests.scala | 4 +- ...ernalAuthenticationRuleSettingsTests.scala | 4 +- ...ternalAuthorizationRuleSettingsTests.scala | 4 +- .../rules/auth/GroupsRuleSettingsTests.scala | 6 +- .../rules/auth/JwtAuthRuleSettingsTests.scala | 4 +- .../auth/LdapAuthRuleSettingsTests.scala | 5 +- .../LdapAuthenticationRuleSettingsTests.scala | 5 +- .../LdapAuthorizationRuleSettingsTests.scala | 4 +- .../auth/ProxyAuthRuleSettingsTests.scala | 4 +- .../auth/RorKbnAuthRuleSettingsTests.scala | 4 +- ...orKbnAuthenticationRuleSettingsTests.scala | 9 +- ...RorKbnAuthorizationRuleSettingsTests.scala | 8 +- ...TokenAuthenticationRuleSettingsTests.scala | 4 +- .../rules/auth/UsersRuleSettingsTests.scala | 4 +- .../ActionRuleSettingsTests.scala | 4 +- .../DataStreamsRuleSettingsTest.scala | 4 +- .../FieldsRuleSettingsTest.scala | 4 +- .../FilterRuleSettingsTests.scala | 4 +- .../IndicesRuleSettingsTests.scala | 4 +- .../RepositoriesRuleSettingsTest.scala | 4 +- .../ResponseFieldsRuleSettingsTest.scala | 4 +- .../SnapshotsRuleSettingsTest.scala | 4 +- .../http/HeadersAndRuleSettingsTests.scala | 4 +- .../http/HeadersOrRuleSettingsTests.scala | 4 +- .../http/MaxBodyLengthRuleSettingsTests.scala | 4 +- .../rules/http/MethodsRuleSettingsTests.scala | 4 +- .../SessionMaxIdleRuleSettingsTests.scala | 4 +- .../http/UriRegexRuleSettingsTests.scala | 4 +- .../http/XForwardedForRuleSettingsTests.scala | 4 +- .../KibanaAccessRuleSettingsTests.scala | 4 +- .../KibanaHideAppsRuleSettingsTests.scala | 4 +- .../kibana/KibanaIndexRuleSettingsTests.scala | 4 +- .../KibanaUserDataRuleSettingsTests.scala | 4 +- .../transport/HostsRuleSettingsTests.scala | 4 +- .../LocalHostsRuleSettingsTests.scala | 4 +- .../unit/acl/logging/AuditingToolTests.scala | 2 +- .../ror/unit/utils/RorYamlParserTests.scala | 2 +- .../suites/AdminApiAuthMockSuite.scala | 10 +- .../suites/ImpersonationSuite.scala | 8 +- .../LocalClusterAuditingToolsSuite.scala | 4 +- .../suites/base/BaseAdminApiSuite.scala | 106 +++++++++--------- .../suites/base/BaseAuditingToolsSuite.scala | 16 +-- ...sterWithRorNodesAndInternodeSslSuite.scala | 2 +- .../SingletonEsContainerWithRorSecurity.scala | 4 +- .../utils/elasticsearch/RorApiManager.scala | 82 +++++++------- 59 files changed, 227 insertions(+), 228 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala index c79c91a551..8f9322301a 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/auth/RorKbnRulesDecoders.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.accesscontrol.blocks.rules.auth.{RorKbnAuthRule, RorKbnAut import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupIdPattern import tech.beshu.ror.accesscontrol.domain.{GroupIds, GroupsLogic} import tech.beshu.ror.accesscontrol.factory.GlobalSettings -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.Message -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.RulesLevelCreationError +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.Message +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.accesscontrol.factory.decoders.definitions.Definitions import tech.beshu.ror.accesscontrol.factory.decoders.definitions.RorKbnDefinitionsDecoder.* import tech.beshu.ror.accesscontrol.factory.decoders.rules.RuleBaseDecoder.RuleBaseDecoderWithoutAssociatedFields diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala index 1df17f2f65..ee6d769756 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/decoders/rules/kibana/KibanaRulesDecoders.scala @@ -66,12 +66,12 @@ class KibanaTemplateIndexRuleDecoder(variableCreator: RuntimeResolvableVariableC } } -class KibanaAccessRuleDecoder(rorIndexNameConfiguration: RorSettingsIndex) +class KibanaAccessRuleDecoder(rorIndexName: RorSettingsIndex) extends RuleBaseDecoderWithoutAssociatedFields[KibanaAccessRule] { override protected def decoder: Decoder[RuleDefinition[KibanaAccessRule]] = { Decoder[KibanaAccess] - .map(KibanaAccessRule.Settings(_, rorIndexNameConfiguration)) + .map(KibanaAccessRule.Settings(_, rorIndexName)) .map(settings => new KibanaAccessRule(settings)) .map(RuleDefinition.create(_)) .decoder diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala index 5352934d7d..fe3296cf9c 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala @@ -45,7 +45,7 @@ object RorSettingsSourcesConfig extends YamlFileBasedSettingsLoaderSupport { rorSettingsFile, rorSettingsMaxSize ) - loadSetting[RorSettingsSourcesConfig](esEnv, "ROR settings source config") + loadSetting[RorSettingsSourcesConfig](esEnv, "ROR settings source settings") } private object decoders { diff --git a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthenticationYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthenticationYamlLoadedAccessControlTests.scala index ebf78d44b8..cedb2b2cb2 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthenticationYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthenticationYamlLoadedAccessControlTests.scala @@ -34,7 +34,7 @@ import tech.beshu.ror.utils.misc.JwtUtils.ClaimKeyOps class RorKbnAuthenticationYamlLoadedAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | access_control_rules: @@ -74,7 +74,7 @@ class RorKbnAuthenticationYamlLoadedAccessControlTests """.stripMargin "An ACL" when { - "is configured using config above" should { + "is configured using settings above" should { "allow to proceed" when { "JWT token is defined with empty groups" in { val jwt = JwtUtils.Jwt( diff --git a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthnAndAuthzYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthnAndAuthzYamlLoadedAccessControlTests.scala index bc6c256cc4..62a3c990c2 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthnAndAuthzYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/RorKbnAuthnAndAuthzYamlLoadedAccessControlTests.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.utils.misc.JwtUtils.ClaimKeyOps class RorKbnAuthnAndAuthzYamlLoadedAccessControlTests extends AnyWordSpec with BaseYamlLoadedAccessControlTest with Inside { - override protected def configYaml: String = + override protected def settingsYaml: String = """ |readonlyrest: | access_control_rules: @@ -80,7 +80,7 @@ class RorKbnAuthnAndAuthzYamlLoadedAccessControlTests """.stripMargin "An ACL" when { - "is configured using config above" should { + "is configured using settings above" should { "allow to proceed" when { "JWT token is defined" in { val jwt = JwtUtils.Jwt( diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 25f4793706..96d7d84ae5 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -321,12 +321,12 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { | |""".stripMargin - impersonationWarningsReader(config, NoOpMocksProvider).read() should be(List( + impersonationWarningsReader(settings, NoOpMocksProvider).read() should be(List( impersonationNotSupportedWarning("test_block1", "ror_kbn_auth") )) } "ror kbn auth rule (configured without groups)" in { - val config = + val settings = """ |readonlyrest: | diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala index f5b8bbb06a..77539529d3 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/LocalUsersTest.scala @@ -211,7 +211,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { } } "ror_kbn_auth rule used" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -252,10 +252,10 @@ class LocalUsersTest extends AnyWordSpec with Inside { | signature_key: "1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890" |""".stripMargin - val rorConfig = rorConfigFromUnsafe(config) - inside(createCore(rorConfig, new UnboundidLdapConnectionPoolProvider())) { + val rorSettings = rorSettingsFromUnsafe(settings) + inside(createCore(rorSettings, new UnboundidLdapConnectionPoolProvider())) { case Right(core) => - core.rorConfig.localUsers should be(allUsersResolved(Set( + core.dependencies.localUsers should be(allUsersResolved(Set( User.Id("admin"), User.Id("cartman"), User.Id("Bìlbö Bággįnš"), User.Id("bong"), User.Id("morgan") ))) case Left(error) => @@ -263,7 +263,7 @@ class LocalUsersTest extends AnyWordSpec with Inside { } } "ror_kbn_authentication rule used" in { - val config = + val settings = s""" |readonlyrest: | access_control_rules: @@ -304,10 +304,10 @@ class LocalUsersTest extends AnyWordSpec with Inside { | signature_key: "1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890" |""".stripMargin - val rorConfig = rorConfigFromUnsafe(config) - inside(createCore(rorConfig, new UnboundidLdapConnectionPoolProvider())) { + val rorSettings = rorSettingsFromUnsafe(settings) + inside(createCore(rorSettings, new UnboundidLdapConnectionPoolProvider())) { case Right(core) => - core.rorConfig.localUsers should be(allUsersResolved(Set( + core.dependencies.localUsers should be(allUsersResolved(Set( User.Id("admin"), User.Id("cartman"), User.Id("Bìlbö Bággįnš"), User.Id("bong"), User.Id("morgan") ))) case Left(error) => diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala index 761bb2a54d..c6724ad8a3 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/ImpersonationSettingsTests.scala @@ -49,7 +49,7 @@ class ImpersonationSettingsTests extends BaseDecoderTest( ) { "An impersonation definition" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one impersonator is defined" which { "using auth key as authentication method" in { assertDecodingSuccess( @@ -110,7 +110,7 @@ class ImpersonationSettingsTests extends BaseDecoderTest( ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "impersonation section is empty" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala index d610af228f..a3cc5269b7 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala @@ -74,7 +74,7 @@ class LdapServicesSettingsTests private(ldapConnectionPoolProvider: UnboundidLda ) "An LdapService" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one LDAP service is declared (without server_side_groups_filtering)" in { assertDecodingSuccess( yamls = NonEmptyList.of( @@ -1750,7 +1750,7 @@ class LdapServicesSettingsTests private(ldapConnectionPoolProvider: UnboundidLda ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "circuit breaker config is malformed" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala index c21478c398..5ffcd35a0e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/VariableTransformationAliasesTests.scala @@ -28,7 +28,7 @@ class VariableTransformationAliasesTests extends BaseDecoderTest(VariableTransformationAliasesDefinitionsDecoder.create(SupportedVariablesFunctions.default)) { "A variable transformation aliases definition" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one alias is defined" in { assertDecodingSuccess( yaml = @@ -99,7 +99,7 @@ class VariableTransformationAliasesTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "aliases section is empty" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala index 327307dcf2..d5e9090212 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ApiKeysRuleSettingsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.utils.TestsUtils.* class ApiKeysRuleSettingsTests extends BaseRuleSettingsDecoderTest[ApiKeysRule] { "An ApiKeysRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one api key is defined" in { assertDecodingSuccess( yaml = @@ -64,7 +64,7 @@ class ApiKeysRuleSettingsTests extends BaseRuleSettingsDecoderTest[ApiKeysRule] ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no api key is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala index 4809b5c394..fb3e100fd6 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests.scala @@ -28,7 +28,7 @@ class AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKeyPBKDF2WithHmacSHA512Rule] { "An AuthKeyPBKDF2WithHmacSHA512Rule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "PBKDF2 auth key is defined (all hashed syntax)" in { assertDecodingSuccess( yaml = @@ -68,7 +68,7 @@ class AuthKeyPBKDF2WithHmacSHA512RuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no PBKDF2 auth key is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala index bac56e8148..583900ff3b 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha1RuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.unsafeNes class AuthKeySha1RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKeySha1Rule] { "An AuthKeySha1Rule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "SHA1 auth key is defined (all hashed syntax)" in { assertDecodingSuccess( yaml = @@ -67,7 +67,7 @@ class AuthKeySha1RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKeySh ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no SHA1 auth key is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala index cf72349917..a88a942661 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha256RuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.unsafeNes class AuthKeySha256RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKeySha256Rule] { "An AuthKeySha256Rule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "SHA256 auth key is defined (all hashed syntax)" in { assertDecodingSuccess( yaml = @@ -67,7 +67,7 @@ class AuthKeySha256RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKey ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no SHA256 auth key is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala index 79919038c9..a3cc79e3f0 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/AuthKeySha512RuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.unsafeNes class AuthKeySha512RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKeySha512Rule] { "An AuthKeySha512Rule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "SHA512 auth key is defined (all hashed syntax)" in { assertDecodingSuccess( yaml = @@ -67,7 +67,7 @@ class AuthKeySha512RuleSettingsTests extends BaseRuleSettingsDecoderTest[AuthKey ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no SHA512 auth key is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala index a76815623f..b40eddfb8e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthenticationRuleSettingsTests.scala @@ -31,7 +31,7 @@ class ExternalAuthenticationRuleSettingsTests extends BaseRuleSettingsDecoderTest[ExternalAuthenticationRule] with MockFactory { "An ExternalAuthenticationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one authentication service is declared" in { assertDecodingSuccess( yaml = @@ -191,7 +191,7 @@ class ExternalAuthenticationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "extended version of rule definition doesn't declare cache TTL" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala index ab2cc7e269..27c6e8ef53 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ExternalAuthorizationRuleSettingsTests.scala @@ -42,7 +42,7 @@ class ExternalAuthorizationRuleSettingsTests extends BaseRuleSettingsDecoderTest[ExternalAuthorizationRule] with MockFactory with Inside { "An ExternalAuthorizationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one authorization service is declared" in { assertDecodingSuccess( yaml = @@ -477,7 +477,7 @@ class ExternalAuthorizationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "authorization rule doesn't have service name declared" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala index 7670e6f67f..829d823d39 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/GroupsRuleSettingsTests.scala @@ -71,7 +71,7 @@ class GroupsRuleSettingsTests forAll(simpleSyntaxTestParams) { (simpleSyntaxName, creator) => s"A GroupsRule settings test for $simpleSyntaxName" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "a groups mapping is not used" when { "only one group is defined" when { "one, full username is used" in { @@ -724,7 +724,7 @@ class GroupsRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "groups section is defined, but without any group" in { assertDecodingFailure( yaml = @@ -1453,7 +1453,7 @@ class GroupsRuleSettingsTests } s"A Combined GroupsRule settings" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "a groups mapping is not used" when { "only one group is defined" when { "one, full username is used" in { diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala index 5d8ed33bf7..13b5b8263c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/JwtAuthRuleSettingsTests.scala @@ -43,7 +43,7 @@ class JwtAuthRuleSettingsTests with MockFactory { "A JwtAuthRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "rule is defined using simplified version and minimal required set of fields in JWT definition" in { assertDecodingSuccess( yaml = @@ -593,7 +593,7 @@ class JwtAuthRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no JWT definition name is defined in rule setting" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala index 46557840e9..cebc285b3c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthRuleSettingsTests.scala @@ -22,13 +22,12 @@ import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreC import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.SingletonLdapContainers -import tech.beshu.ror.utils.TestsUtils.unsafeNes class LdapAuthRuleSettingsTests extends BaseRuleSettingsDecoderTest[LdapAuthRule] { "An LdapAuthRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "there is LDAP service with given name and groups are defined" in { assertDecodingSuccess( yaml = @@ -88,7 +87,7 @@ class LdapAuthRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no LDAP service with given name is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala index ed049458f2..2d5bb35640 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthenticationRuleSettingsTests.scala @@ -22,13 +22,12 @@ import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreC import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.RulesLevelCreationError import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest import tech.beshu.ror.utils.SingletonLdapContainers -import tech.beshu.ror.utils.TestsUtils.unsafeNes class LdapAuthenticationRuleSettingsTests extends BaseRuleSettingsDecoderTest[LdapAuthenticationRule] { "An LdapAuthenticationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "simple version of LDAP authentication rule is used" in { assertDecodingSuccess( yaml = @@ -105,7 +104,7 @@ class LdapAuthenticationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no LDAP service with given name is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala index 93078c8c3c..71c221587a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/LdapAuthorizationRuleSettingsTests.scala @@ -31,7 +31,7 @@ class LdapAuthorizationRuleSettingsTests extends BaseRuleSettingsDecoderTest[LdapAuthorizationRule] { "An LdapAuthorizationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "there is LDAP service with given name and groups are defined" in { assertDecodingSuccess( yaml = @@ -580,7 +580,7 @@ class LdapAuthorizationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no LDAP service with given name is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala index b50c7d5514..da8d188c4d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/ProxyAuthRuleSettingsTests.scala @@ -28,7 +28,7 @@ class ProxyAuthRuleSettingsTests extends BaseRuleSettingsDecoderTest[ProxyAuthRule] { "A ProxyAuthRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one user is defined" in { assertDecodingSuccess( yaml = @@ -135,7 +135,7 @@ class ProxyAuthRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no proxy_auth data is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala index 5d5f3d2ba4..3e759ed1cd 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthRuleSettingsTests.scala @@ -37,7 +37,7 @@ class RorKbnAuthRuleSettingsTests extends BaseRuleSettingsDecoderTest[RorKbnAuthRule] { "A RorKbnAuthRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "rule is defined using extended version with groups or logic and minimal request set of fields in ROR kbn definition" in { val rolesKeys = List("roles", "groups", "groups_or") rolesKeys.foreach { roleKey => @@ -108,7 +108,7 @@ class RorKbnAuthRuleSettingsTests } } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no ROR kbn definition name is defined in rule setting" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala index 2ffc8a5a44..228d7cd60a 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthenticationRuleSettingsTests.scala @@ -20,8 +20,9 @@ import org.scalatest.matchers.should.Matchers.* import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef.SignatureCheckMethod import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthenticationRule -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} + +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.EnvVarsProvider import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest @@ -34,7 +35,7 @@ class RorKbnAuthenticationRuleSettingsTests extends BaseRuleSettingsDecoderTest[RorKbnAuthenticationRule] { "A RorKbnAuthenticationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "rule is defined using simplified version and minimal required set of fields in ROR kbn definition" in { assertDecodingSuccess( yaml = @@ -184,7 +185,7 @@ class RorKbnAuthenticationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "rule is defined with groups" in { val rolesKeys = List("roles_and", "groups_and") rolesKeys.foreach { roleKey => diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala index 52bb7fd7a3..3150e040b5 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/RorKbnAuthorizationRuleSettingsTests.scala @@ -22,8 +22,8 @@ import tech.beshu.ror.accesscontrol.blocks.definitions.RorKbnDef.SignatureCheckM import tech.beshu.ror.accesscontrol.blocks.rules.auth.RorKbnAuthorizationRule import tech.beshu.ror.accesscontrol.domain.GroupIdLike.GroupId import tech.beshu.ror.accesscontrol.domain.{GroupIdLike, GroupIds, GroupsLogic} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} -import tech.beshu.ror.accesscontrol.factory.RawRorConfigBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.Reason.{MalformedValue, Message} +import tech.beshu.ror.accesscontrol.factory.RawRorSettingsBasedCoreFactory.CoreCreationError.{DefinitionsLevelCreationError, GeneralReadonlyrestSettingsError, RulesLevelCreationError} import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.EnvVarsProvider import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTest @@ -37,7 +37,7 @@ class RorKbnAuthorizationRuleSettingsTests extends BaseRuleSettingsDecoderTest[RorKbnAuthorizationRule] { "A RorKbnAuthorizationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "rule is defined using extended version with groups or logic and minimal request set of fields in ROR kbn definition" in { val rolesKeys = List("roles", "groups", "groups_or") rolesKeys.foreach { roleKey => @@ -106,7 +106,7 @@ class RorKbnAuthorizationRuleSettingsTests } } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no ROR kbn definition name is defined in rule setting" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala index e4e4c891a0..889d7a1437 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/TokenAuthenticationRuleSettingsTests.scala @@ -31,7 +31,7 @@ class TokenAuthenticationRuleSettingsTests extends BaseRuleSettingsDecoderTest[TokenAuthenticationRule] { "A TokenAuthenticationRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "token and username defined" in { assertDecodingSuccess( yaml = @@ -119,7 +119,7 @@ class TokenAuthenticationRuleSettingsTests ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "username is not defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala index e846477451..f130fb09a9 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/auth/UsersRuleSettingsTests.scala @@ -45,7 +45,7 @@ class UsersRuleSettingsTests extends BaseRuleSettingsDecoderTest[UsersRule] { ) "A UsersRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one user is defined" in { assertDecodingSuccess( yaml = @@ -104,7 +104,7 @@ class UsersRuleSettingsTests extends BaseRuleSettingsDecoderTest[UsersRule] { ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no user is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala index 915d11747c..a28c0433a1 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ActionRuleSettingsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTes class ActionRuleSettingsTests extends BaseRuleSettingsDecoderTest[ActionsRule] { "An ActionRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one action is defined" in { assertDecodingSuccess( yaml = @@ -64,7 +64,7 @@ class ActionRuleSettingsTests extends BaseRuleSettingsDecoderTest[ActionsRule] { ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no action is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala index da0bdca51b..6d1b411ecb 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/DataStreamsRuleSettingsTest.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class DataStreamsRuleSettingsTest extends BaseRuleSettingsDecoderTest[DataStreamsRule] { "A DataStreamsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one data stream is defined" in { assertDecodingSuccess( yaml = @@ -113,7 +113,7 @@ class DataStreamsRuleSettingsTest extends BaseRuleSettingsDecoderTest[DataStream ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no data stream is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala index 680308a8dd..4e66aadc77 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FieldsRuleSettingsTest.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.utils.TestsUtils.* class FieldsRuleSettingsTest extends BaseRuleSettingsDecoderTest[FieldsRule] { "A FieldsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "ror is run in plugin mode and" when { "only one field is defined" in { assertDecodingSuccess( @@ -171,7 +171,7 @@ class FieldsRuleSettingsTest extends BaseRuleSettingsDecoderTest[FieldsRule] { } } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no field is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala index 64f257ff41..9b67346d9c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/FilterRuleSettingsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.utils.TestsUtils.unsafeNes class FilterRuleSettingsTests extends BaseRuleSettingsDecoderTest[FilterRule] { "A FilterRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "filter is defined" in { assertDecodingSuccess( yaml = @@ -65,7 +65,7 @@ class FilterRuleSettingsTests extends BaseRuleSettingsDecoderTest[FilterRule] { ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no filter is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala index 14277acbac..af95c76abd 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/IndicesRuleSettingsTests.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class IndicesRuleSettingsTests extends BaseRuleSettingsDecoderTest[IndicesRule] { "An IndicesRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one index is defined" in { assertDecodingSuccess( yaml = @@ -240,7 +240,7 @@ class IndicesRuleSettingsTests extends BaseRuleSettingsDecoderTest[IndicesRule] ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no index is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala index 4de34b0ef4..ce959fb81f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/RepositoriesRuleSettingsTest.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class RepositoriesRuleSettingsTest extends BaseRuleSettingsDecoderTest[RepositoriesRule] { "A RepositoriesRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one repository is defined" in { assertDecodingSuccess( yaml = @@ -114,7 +114,7 @@ class RepositoriesRuleSettingsTest extends BaseRuleSettingsDecoderTest[Repositor ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no repository is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala index 910673ba43..af7f823f4d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/ResponseFieldsRuleSettingsTest.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.utils.TestsUtils.* class ResponseFieldsRuleSettingsTest extends BaseRuleSettingsDecoderTest[ResponseFieldsRule] { "A ResponseFieldsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "ror is run in plugin mode and" when { "only one field is defined" in { assertDecodingSuccess( @@ -142,7 +142,7 @@ class ResponseFieldsRuleSettingsTest extends BaseRuleSettingsDecoderTest[Respons } } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no field is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala index 3213e38ef1..2a3698ad60 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/elasticsearch/SnapshotsRuleSettingsTest.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class SnapshotsRuleSettingsTest extends BaseRuleSettingsDecoderTest[SnapshotsRule] { "A SnapshotsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one snapshot is defined" in { assertDecodingSuccess( yaml = @@ -113,7 +113,7 @@ class SnapshotsRuleSettingsTest extends BaseRuleSettingsDecoderTest[SnapshotsRul ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no snapshot is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala index 232e95504f..2f1285b953 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersAndRuleSettingsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.utils.TestsUtils.* class HeadersAndRuleSettingsTests extends BaseRuleSettingsDecoderTest[HeadersAndRule] { "A HeadersAndRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one header requirement is defined" in { assertDecodingSuccess( yaml = @@ -111,7 +111,7 @@ class HeadersAndRuleSettingsTests extends BaseRuleSettingsDecoderTest[HeadersAnd ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no header is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala index 08c41a7a08..5421d44736 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/HeadersOrRuleSettingsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.utils.TestsUtils.* class HeadersOrRuleSettingsTests extends BaseRuleSettingsDecoderTest[HeadersOrRule] { "A HeadersOrRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one header requirement is defined" in { assertDecodingSuccess( yaml = @@ -92,7 +92,7 @@ class HeadersOrRuleSettingsTests extends BaseRuleSettingsDecoderTest[HeadersOrRu ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no header is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala index 80e5c03fcd..36b4bb069d 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MaxBodyLengthRuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTes class MaxBodyLengthRuleSettingsTests extends BaseRuleSettingsDecoderTest[MaxBodyLengthRule] { "A MaxBodyLengthRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "max body length > 0 is defined" in { assertDecodingSuccess( yaml = @@ -63,7 +63,7 @@ class MaxBodyLengthRuleSettingsTests extends BaseRuleSettingsDecoderTest[MaxBody ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "max body length field is defined, but no value it set" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala index f87a2bc474..349c347738 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/MethodsRuleSettingsTests.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.unit.acl.factory.decoders.rules.BaseRuleSettingsDecoderTes class MethodsRuleSettingsTests extends BaseRuleSettingsDecoderTest[MethodsRule] { "A MethodsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "one http method is defined" in { assertDecodingSuccess( yaml = @@ -66,7 +66,7 @@ class MethodsRuleSettingsTests extends BaseRuleSettingsDecoderTest[MethodsRule] ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no http method is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala index 09587beda0..ad448384cc 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/SessionMaxIdleRuleSettingsTests.scala @@ -30,7 +30,7 @@ import scala.language.postfixOps class SessionMaxIdleRuleSettingsTests extends BaseRuleSettingsDecoderTest[SessionMaxIdleRule] { "A SessionMaxIdleRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "max idle time of session is > 0s" in { assertDecodingSuccess( yaml = @@ -66,7 +66,7 @@ class SessionMaxIdleRuleSettingsTests extends BaseRuleSettingsDecoderTest[Sessio ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "session max idle time is not defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala index 51c324fd38..e26570eb25 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/UriRegexRuleSettingsTests.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.syntax.* class UriRegexRuleSettingsTests extends BaseRuleSettingsDecoderTest[UriRegexRule] with MockFactory { "A UriRegexRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "single uri pattern is defined" in { assertDecodingSuccess( yaml = @@ -117,7 +117,7 @@ class UriRegexRuleSettingsTests extends BaseRuleSettingsDecoderTest[UriRegexRule ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no uri pattern is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala index 6b859fe298..ae76dbe34e 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/http/XForwardedForRuleSettingsTests.scala @@ -32,7 +32,7 @@ import tech.beshu.ror.utils.TestsUtils.* class XForwardedForRuleSettingsTests extends BaseRuleSettingsDecoderTest[XForwardedForRule] { "A XForwardedForRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one address is defined" in { assertDecodingSuccess( yaml = @@ -148,7 +148,7 @@ class XForwardedForRuleSettingsTests extends BaseRuleSettingsDecoderTest[XForwar ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no address or ip is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala index f2b8b06db1..afce19cc75 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaAccessRuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.unsafeNes class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAccessRule] { "A KibanaAccess" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "ro access is defined" in { assertDecodingSuccess( yaml = @@ -137,7 +137,7 @@ class KibanaAccessRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaAc ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no access is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala index 846f4fd6e7..a67cbce562 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaHideAppsRuleSettingsTests.scala @@ -28,7 +28,7 @@ import tech.beshu.ror.utils.uniquelist.UniqueNonEmptyList class KibanaHideAppsRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaHideAppsRule] { "A KibanaHideAppsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one kibana app is defined" in { assertDecodingSuccess( yaml = @@ -68,7 +68,7 @@ class KibanaHideAppsRuleSettingsTests extends BaseRuleSettingsDecoderTest[Kibana ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "empty string kibana app is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala index abf04cf91a..4c90a1a455 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaIndexRuleSettingsTests.scala @@ -27,7 +27,7 @@ import tech.beshu.ror.utils.TestsUtils.* class KibanaIndexRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaIndexRule] { "A KibanaIndexRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "kibana index is defined" in { assertDecodingSuccess( yaml = @@ -64,7 +64,7 @@ class KibanaIndexRuleSettingsTests extends BaseRuleSettingsDecoderTest[KibanaInd ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no kibana index is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala index 763cf55886..9bb8624743 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/kibana/KibanaUserDataRuleSettingsTests.scala @@ -40,7 +40,7 @@ class KibanaUserDataRuleSettingsTests with OptionValues with EitherValues { "A KibanaUserDataRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "all required properties are set" in { assertDecodingSuccess( yaml = @@ -583,7 +583,7 @@ class KibanaUserDataRuleSettingsTests } } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "some of the required properties are not set" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala index f25cefd255..82e478b9af 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/HostsRuleSettingsTests.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class HostsRuleSettingsTests extends BaseRuleSettingsDecoderTest[HostsRule] { "A HostsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one host is defined" in { assertDecodingSuccess( yaml = @@ -113,7 +113,7 @@ class HostsRuleSettingsTests extends BaseRuleSettingsDecoderTest[HostsRule] { ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no host is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala index 0648ce02c0..1a7c8d5333 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/rules/transport/LocalHostsRuleSettingsTests.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.utils.TestsUtils.* class LocalHostsRuleSettingsTests extends BaseRuleSettingsDecoderTest[LocalHostsRule] { "A LocalHostsRule" should { - "be able to be loaded from config" when { + "be able to be loaded from settings" when { "only one host is defined" in { assertDecodingSuccess( yaml = @@ -90,7 +90,7 @@ class LocalHostsRuleSettingsTests extends BaseRuleSettingsDecoderTest[LocalHosts ) } } - "not be able to be loaded from config" when { + "not be able to be loaded from settings" when { "no host is defined" in { assertDecodingFailure( yaml = diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala index 8e01c28af8..b407310d26 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/logging/AuditingToolTests.scala @@ -179,7 +179,7 @@ class AuditingToolTests extends AnyWordSpec with MockFactory with BeforeAndAfter } } "log sink is used" should { - "saved audit log to file defined in log4j config" in { + "saved audit log to file defined in log4j settings" in { @nowarn("cat=deprecation") val auditingTool = AuditingTool.create( settings = AuditSettings( diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala index 1bcd3f1264..0cc5a6898c 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/RorYamlParserTests.scala @@ -132,7 +132,7 @@ class RorYamlParserTests extends AnyWordSpec with Inside with Matchers { } } } - "return valid ror config" when { + "return valid ror settings" when { "none of the keys is duplicated within its scope" in { val rawConfig = """ diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index 0018c5a445..b4438bd102 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -192,7 +192,7 @@ class AdminApiAuthMockSuite )) rorClients.foreach { rorApiManager => - val testConfigResponse = rorApiManager.currentRorTestConfig + val testConfigResponse = rorApiManager.currentRorTestSettings testConfigResponse.responseJson("status").str should be("TEST_SETTINGS_PRESENT") testConfigResponse.responseJson("warnings") should be( ujson.read( @@ -660,7 +660,7 @@ class AdminApiAuthMockSuite } rorClients.foreach { rorApiManager => - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_PRESENT") response.responseJson("warnings") should be(ujson.read( @@ -1236,7 +1236,7 @@ class AdminApiAuthMockSuite private def invalidateTestSettingsOnAllNodes(): Unit = { rorClients.head - .invalidateRorTestConfig() + .invalidateRorTestSettings() .forceOkStatus() eventually { // await until all nodes load config @@ -1247,7 +1247,7 @@ class AdminApiAuthMockSuite } private def assertTestSettings(rorApiManager: RorApiManager, expectedStatus: String) = { - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be(expectedStatus) } @@ -1326,7 +1326,7 @@ class AdminApiAuthMockSuite private def setupTestSettingsOnAllNodes(): Unit = { rorClients.head - .updateRorTestConfig(testEngineConfig()) + .updateRorTestSettings(testEngineConfig()) .forceOkStatus() eventually { // await until all nodes load config diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala index 2010c17713..aa4fd801b8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala @@ -55,7 +55,7 @@ class ImpersonationSuite super.beforeAll() loadTestSettings() rorApiManager - .updateRorInIndexConfig( // In a test, the main engine config should be different from the test config to prevent accidental use of the main engine + .updateRorInIndexSettings( // In a test, the main engine config should be different from the test config to prevent accidental use of the main engine s""" |readonlyrest: | access_control_rules: @@ -555,7 +555,7 @@ class ImpersonationSuite } "test engine is not configured" in { impersonatingSearchManagers("admin1", "pass", impersonatedUser = "ldap_user_1").foreach { searchManager => - rorApiManager.invalidateRorTestConfig().forceOkStatus() + rorApiManager.invalidateRorTestSettings().forceOkStatus() loadTestSettings() rorApiManager @@ -593,7 +593,7 @@ class ImpersonationSuite val result1 = searchManager.search("test3_index") result1 should have statusCode 200 - rorApiManager.invalidateRorTestConfig().forceOkStatus() + rorApiManager.invalidateRorTestSettings().forceOkStatus() val result2 = searchManager.search("test3_index") result2 should have statusCode 403 @@ -699,7 +699,7 @@ class ImpersonationSuite private def loadTestSettings(): Unit = { rorApiManager - .updateRorTestConfig(resolvedRorConfigFile.contentAsString) + .updateRorTestSettings(resolvedRorConfigFile.contentAsString) .forceOkStatus() } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala index c7f616c985..5e673d5c39 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala @@ -190,7 +190,7 @@ class LocalClusterAuditingToolsSuite private def updateRorConfig(originalString: String, newString: String) = { val initialConfig = getResourceContent(rorConfigFileName) val modifiedConfig = initialConfig.replace(originalString, newString) - rorApiManager.updateRorInIndexConfig(modifiedConfig).forceOKStatusOrConfigAlreadyLoaded() - rorApiManager.reloadRorConfig().force() + rorApiManager.updateRorInIndexSettings(modifiedConfig).forceOKStatusOrSettingsAlreadyLoaded() + rorApiManager.reloadRorSettings().force() } } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala index cb0f5a8f58..4c4efd92f9 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala @@ -69,17 +69,17 @@ trait BaseAdminApiSuite override lazy val clusterContainers = NonEmptyList.of(rorWithIndexConfig, rorWithNoIndexConfig) "An admin REST API" should { - "provide a method for force refresh ROR config" which { + "provide a method for force refresh ROR settings" which { "is going to reload ROR core" when { "in-index config is newer than current one" in { rorWithNoIndexConfigAdminActionManager - .insertInIndexConfigDirectlyToRorIndex( - rorConfigIndex = readonlyrestIndexName, - config = getResourceContent("/admin_api/readonlyrest_index.yml") + .insertInIndexSettingsDirectlyToRorIndex( + rorIndex = readonlyrestIndexName, + Settings = getResourceContent("/admin_api/readonlyrest_index.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorConfig() + val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -94,13 +94,13 @@ trait BaseAdminApiSuite "return info that config is up to date" when { "in-index config is the same as current one" in { rorWithNoIndexConfigAdminActionManager - .insertInIndexConfigDirectlyToRorIndex( - rorConfigIndex = readonlyrestIndexName, - config = getResourceContent("/admin_api/readonlyrest.yml") + .insertInIndexSettingsDirectlyToRorIndex( + rorIndex = readonlyrestIndexName, + Settings = getResourceContent("/admin_api/readonlyrest.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorConfig() + val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -114,7 +114,7 @@ trait BaseAdminApiSuite } "return info that in-index config does not exist" when { "there is no in-index settings configured yet" in { - val result = rorWithNoIndexConfigAdminActionManager.reloadRorConfig() + val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( s""" @@ -126,16 +126,16 @@ trait BaseAdminApiSuite )) } } - "return info that cannot reload config" when { + "return info that cannot reload settings" when { "config cannot be reloaded (eg. because LDAP is not achievable)" in { rorWithNoIndexConfigAdminActionManager - .insertInIndexConfigDirectlyToRorIndex( - rorConfigIndex = readonlyrestIndexName, - config = getResourceContent("/admin_api/readonlyrest_with_ldap.yml") + .insertInIndexSettingsDirectlyToRorIndex( + rorIndex = readonlyrestIndexName, + Settings = getResourceContent("/admin_api/readonlyrest_with_ldap.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorConfig() + val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -148,11 +148,11 @@ trait BaseAdminApiSuite } } } - "provide a method for update in-index config" which { - "is going to reload ROR core and store new in-index config" when { + "provide a method for update in-index settings" which { + "is going to reload ROR core and store new in-index settings" when { "configuration is new and correct" in { def forceReload(rorSettingsResource: String) = { - val result = ror1WithIndexConfigAdminActionManager.updateRorInIndexConfig(getResourceContent(rorSettingsResource)) + val result = ror1WithIndexConfigAdminActionManager.updateRorInIndexSettings(getResourceContent(rorSettingsResource)) result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -214,7 +214,7 @@ trait BaseAdminApiSuite "return info that config is up to date" when { "in-index config is the same as provided one" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_index.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_index.yml")) assertSettingsInIndex(getResourceContent("/admin_api/readonlyrest_index.yml")) result should have statusCode 200 @@ -231,7 +231,7 @@ trait BaseAdminApiSuite "return info that config is malformed" when { "invalid YAML is provided" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_malformed.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_malformed.yml")) result should have statusCode 200 result.responseJson("status").str should be("ko") @@ -241,7 +241,7 @@ trait BaseAdminApiSuite "return info that request is malformed" when { "settings key missing" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfigRaw(rawRequestBody = "{}") + .updateRorInIndexSettingsRaw(rawRequestBody = "{}") result should have statusCode 400 result.responseJson should be(ujson.read( @@ -257,7 +257,7 @@ trait BaseAdminApiSuite "return info that cannot reload" when { "ROR core cannot be reloaded" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_with_ldap.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_with_ldap.yml")) result should have statusCode 200 result.responseJson should be(ujson.read( @@ -271,11 +271,11 @@ trait BaseAdminApiSuite } } } - "provide a method for fetching current in-index config" which { - "return current config" when { + "provide a method for fetching current in-index settings" which { + "return current settings" when { "there is one in index" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_first_update.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_first_update.yml")) result should have statusCode 200 result.responseJson should be(ujson.read( @@ -289,7 +289,7 @@ trait BaseAdminApiSuite assertSettingsInIndex(getResourceContent("/admin_api/readonlyrest_first_update.yml")) - val getIndexConfigResult = ror1WithIndexConfigAdminActionManager.getRorInIndexConfig + val getIndexConfigResult = ror1WithIndexConfigAdminActionManager.getRorInIndexSettings result should have statusCode 200 getIndexConfigResult.responseJson("status").str should be("ok") getIndexConfigResult.responseJson("message").str should be { @@ -297,13 +297,13 @@ trait BaseAdminApiSuite } } } - "return info that there is no in-index config" when { + "return info that there is no in-index settings" when { "there is no index" in { assertNoRorConfigInIndex(rorWithNoIndexConfigAdminActionManager) } "there is no config document in index" in { val result = ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_first_update.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_first_update.yml")) result should have statusCode 200 result.responseJson should be(ujson.read( @@ -324,9 +324,9 @@ trait BaseAdminApiSuite } } } - "provide a method for fetching current file config" which { - "return current config" in { - val result = ror1WithIndexConfigAdminActionManager.getRorFileConfig + "provide a method for fetching current file settings" which { + "return current settings" in { + val result = ror1WithIndexConfigAdminActionManager.getRorFileSettings result should have statusCode 200 result.responseJson("status").str should be("ok") result.responseJson("message").str should be(getResourceContent("/admin_api/readonlyrest.yml")) @@ -495,7 +495,7 @@ trait BaseAdminApiSuite eventually { // await until all nodes load config rorClients.foreach { rorApiManager => - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_PRESENT") } @@ -608,7 +608,7 @@ trait BaseAdminApiSuite eventually { rorClients.foreach { rorApiManager => - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_INVALIDATED") response.responseJson("message").str should be("ROR Test settings are invalidated") @@ -739,7 +739,7 @@ trait BaseAdminApiSuite val timestamps = rorClients - .map(_.currentRorTestConfig.responseJson("valid_to").str) + .map(_.currentRorTestSettings.responseJson("valid_to").str) .map(Instant.parse).toSet timestamps.size should be(1) @@ -758,7 +758,7 @@ trait BaseAdminApiSuite val timestampsAfterReload = rorClients - .map(_.currentRorTestConfig.responseJson("valid_to").str) + .map(_.currentRorTestSettings.responseJson("valid_to").str) .map(Instant.parse) .toSet timestampsAfterReload.size should be(1) @@ -773,7 +773,7 @@ trait BaseAdminApiSuite rorClients.foreach { rorApiManager => val result = rorApiManager - .updateRorTestConfigRaw(rawRequestBody = requestBody) + .updateRorTestSettingsRaw(rawRequestBody = requestBody) result should have statusCode 400 result.responseJson should be(ujson.read( @@ -790,7 +790,7 @@ trait BaseAdminApiSuite val requestBody = s"""{"ttl": "30 m"}""" rorClients.foreach { rorApiManager => val result = rorApiManager - .updateRorTestConfigRaw(rawRequestBody = requestBody) + .updateRorTestSettingsRaw(rawRequestBody = requestBody) result should have statusCode 400 result.responseJson should be(ujson.read( @@ -809,7 +809,7 @@ trait BaseAdminApiSuite rorClients.foreach { rorApiManager => val result = rorApiManager - .updateRorTestConfigRaw(rawRequestBody = requestBody) + .updateRorTestSettingsRaw(rawRequestBody = requestBody) result should have statusCode 400 result.responseJson should be(ujson.read( @@ -827,7 +827,7 @@ trait BaseAdminApiSuite "invalid YAML is provided" in { rorClients.foreach { rorApiManager => val result = rorApiManager - .updateRorTestConfig(getResourceContent("/admin_api/readonlyrest_malformed.yml")) + .updateRorTestSettings(getResourceContent("/admin_api/readonlyrest_malformed.yml")) result should have statusCode 200 result.responseJson("status").str should be("FAILED") @@ -839,7 +839,7 @@ trait BaseAdminApiSuite "ROR core cannot be reloaded" in { rorClients.foreach { rorApiManager => val result = rorApiManager - .updateRorTestConfig(getResourceContent("/admin_api/readonlyrest_with_ldap.yml")) + .updateRorTestSettings(getResourceContent("/admin_api/readonlyrest_with_ldap.yml")) result should have statusCode 200 result.responseJson should be(ujson.read( @@ -931,8 +931,8 @@ trait BaseAdminApiSuite } } "main ROR config and test ROR config coexistence check" when { - "get main ROR index config" should { - "return no index config" when { + "get main ROR index settings" should { + "return no index settings" when { "no main and test config in the index" in { adminIndexManager.removeIndex(readonlyrestIndexName) rorClients.foreach { rorApiManager => @@ -970,7 +970,7 @@ trait BaseAdminApiSuite } } } - "return index config" when { + "return index settings" when { "only main config in the index" in { def forceReloadMainSettings(config: String) = { updateRorMainConfig(rorClients.head, config) @@ -1031,7 +1031,7 @@ trait BaseAdminApiSuite override protected def beforeEach(): Unit = { // back to configuration loaded on container start rorWithNoIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest.yml")) .force() new IndexManager(ror2_1Node.adminClient, esVersionUsed).removeIndex(readonlyrestIndexName) @@ -1039,7 +1039,7 @@ trait BaseAdminApiSuite adminIndexManager.removeIndex(readonlyrestIndexName) ror1WithIndexConfigAdminActionManager - .updateRorInIndexConfig(getResourceContent("/admin_api/readonlyrest_index.yml")) + .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_index.yml")) .force() eventually { // await until all nodes invalidate the config @@ -1095,7 +1095,7 @@ trait BaseAdminApiSuite } private def assertNoRorConfigInIndex(rorApiManager: RorApiManager) = { - val result = rorApiManager.getRorInIndexConfig + val result = rorApiManager.getRorInIndexSettings result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -1108,14 +1108,14 @@ trait BaseAdminApiSuite } private def assertInIndexConfigPresent(rorApiManager: RorApiManager, config: String) = { - val getIndexConfigResult = rorApiManager.getRorInIndexConfig + val getIndexConfigResult = rorApiManager.getRorInIndexSettings getIndexConfigResult should have statusCode 200 getIndexConfigResult.responseJson("status").str should be("ok") getIndexConfigResult.responseJson("message").str should be(config) } private def assertTestSettingsNotConfigured(rorApiManager: RorApiManager) = { - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson should be(ujson.read( """ @@ -1131,7 +1131,7 @@ trait BaseAdminApiSuite testConfig: String, expectedTtl: String, expectedWarningsJson: Value = ujson.read("[]")) = { - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_PRESENT") response.responseJson("settings").str should be(testConfig) @@ -1143,7 +1143,7 @@ trait BaseAdminApiSuite private def assertTestSettingsInvalidated(rorApiManager: RorApiManager, testConfig: String, expectedTtl: String) = { - val response = rorApiManager.currentRorTestConfig + val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_INVALIDATED") response.responseJson("message").str should be("ROR Test settings are invalidated") @@ -1155,7 +1155,7 @@ trait BaseAdminApiSuite testConfig: String, configTtl: FiniteDuration, expectedWarningsJson: Value = ujson.read("[]")) = { - val response = rorApiManager.updateRorTestConfig(testConfig, configTtl) + val response = rorApiManager.updateRorTestSettings(testConfig, configTtl) response should have statusCode 200 response.responseJson("status").str should be("OK") response.responseJson("message").str should be("updated settings") @@ -1164,7 +1164,7 @@ trait BaseAdminApiSuite } private def updateRorMainConfig(rorApiManager: RorApiManager, config: String) = { - val result = rorApiManager.updateRorInIndexConfig(config) + val result = rorApiManager.updateRorInIndexSettings(config) result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -1177,7 +1177,7 @@ trait BaseAdminApiSuite } private def invalidateRorTestConfig(rorApiManager: RorApiManager) = { - val response = rorApiManager.invalidateRorTestConfig() + val response = rorApiManager.invalidateRorTestSettings() response should have statusCode 200 response.responseJson should be(ujson.read( """ diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala index dd728416d5..3b28ebb70b 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala @@ -366,7 +366,7 @@ trait BaseAuditingToolsSuite disableAudit() val newIndex = s"audit-index-${UUID.randomUUID().toString}" - rorApiManager.updateRorInIndexConfig(rorConfigWithIndexAudit(newIndex)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithIndexAudit(newIndex)).forceOkStatus() val adminAuditManager = new AuditIndexManager(destNodeClientProvider.adminClient, esVersionUsed, newIndex) auditEventAssertion(adminAuditManager) @@ -383,7 +383,7 @@ trait BaseAuditingToolsSuite assertDataStreamNotExists(newDataStream) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { val response = dataStreamManager.getAllDataStreams() @@ -418,7 +418,7 @@ trait BaseAuditingToolsSuite val indexLifecycleManager = new IndexLifecycleManager(destNodeClientProvider.adminClient, esVersionUsed) indexLifecycleManager.putPolicyAndWaitForIndexing(id = s"$newDataStream-lifecycle-policy", policy) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -453,7 +453,7 @@ trait BaseAuditingToolsSuite val templateManager = new ComponentTemplateManager(destNodeClientProvider.adminClient, esVersionUsed) templateManager.putTemplateAndWaitForIndexing(templateName = s"$newDataStream-mappings", body = template) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -481,7 +481,7 @@ trait BaseAuditingToolsSuite val templateManager = new ComponentTemplateManager(destNodeClientProvider.adminClient, esVersionUsed) templateManager.putTemplateAndWaitForIndexing(templateName = s"$newDataStream-settings", body = template) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -510,7 +510,7 @@ trait BaseAuditingToolsSuite ) ) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -527,7 +527,7 @@ trait BaseAuditingToolsSuite createAuditDataStream(dataStreamName) - rorApiManager.updateRorInIndexConfig(rorConfigWithDataStreamAudit(dataStreamName)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(dataStreamName)).forceOkStatus() val adminAuditManager = new AuditIndexManager(destNodeClientProvider.adminClient, esVersionUsed, dataStreamName) auditEventAssertion(adminAuditManager) @@ -546,7 +546,7 @@ trait BaseAuditingToolsSuite private def disableAudit(): Unit = { val initialConfig = getResourceContent("/ror_audit/disabled_auditing_tools/readonlyrest.yml") - rorApiManager.updateRorInIndexConfig(initialConfig).forceOKStatusOrConfigAlreadyLoaded() + rorApiManager.updateRorInIndexSettings(initialConfig).forceOKStatusOrSettingsAlreadyLoaded() } private def auditEventAssertion(adminAuditManager: AuditIndexManager) = { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala index f9f0ead53b..ba7635183b 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala @@ -81,7 +81,7 @@ trait XpackClusterWithRorNodesAndInternodeSslSuite val rorApiManager = new RorApiManager(clusterContainer.nodes.head.adminClient, esVersion = esVersionUsed) val updateResult = rorApiManager - .updateRorInIndexConfig(getResourceContent("/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_update.yml")) + .updateRorInIndexSettings(getResourceContent("/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_update.yml")) updateResult should have statusCode 200 updateResult.responseJson("status").str should be("ok") diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala index 445c115b4d..3c83412f68 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala @@ -55,8 +55,8 @@ object SingletonEsContainerWithRorSecurity def updateConfig(rorConfig: String): Unit = { rorApiManager - .updateRorInIndexConfig(rorConfig) - .forceOKStatusOrConfigAlreadyLoaded() + .updateRorInIndexSettings(rorConfig) + .forceOKStatusOrSettingsAlreadyLoaded() } def initNode(nodeDataInitializer: ElasticsearchNodeDataInitializer): Unit = { diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala index 31732c3f6a..b5494a0fb6 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/RorApiManager.scala @@ -44,44 +44,44 @@ class RorApiManager(client: RestClient, call(createSendAuditEventRequest(payload), new RorApiJsonResponse(_)) } - def getRorFileConfig: RorApiJsonResponse = { - call(createGetRorFileConfigRequest(), new RorApiJsonResponse(_)) + def getRorFileSettings: RorApiJsonResponse = { + call(createGetRorFileSettingsRequest(), new RorApiJsonResponse(_)) } - def getRorInIndexConfig: RorApiJsonResponse = { - call(createGetRorInIndexConfigRequest(), new RorApiJsonResponse(_)) + def getRorInIndexSettings: RorApiJsonResponse = { + call(createGetRorInIndexSettingsRequest(), new RorApiJsonResponse(_)) } - def updateRorInIndexConfig(config: String): RorApiResponseWithBusinessStatus = { - call(createUpdateRorInIndexConfigRequest(config), new RorApiResponseWithBusinessStatus(_)) + def updateRorInIndexSettings(settings: String): RorApiResponseWithBusinessStatus = { + call(createUpdateRorInIndexSettingsRequest(settings), new RorApiResponseWithBusinessStatus(_)) } - def updateRorInIndexConfigRaw(rawRequestBody: String): RorApiResponseWithBusinessStatus = { - call(createUpdateRorInIndexConfigRequestFromRaw(rawRequestBody), new RorApiResponseWithBusinessStatus(_)) + def updateRorInIndexSettingsRaw(rawRequestBody: String): RorApiResponseWithBusinessStatus = { + call(createUpdateRorInIndexSettingsRequestFromRaw(rawRequestBody), new RorApiResponseWithBusinessStatus(_)) } - def currentRorTestConfig: RorApiJsonResponse = { - call(createGetTestConfigRequest, new RorApiJsonResponse(_)) + def currentRorTestSettings: RorApiJsonResponse = { + call(createGetTestSettingsRequest, new RorApiJsonResponse(_)) } - def updateRorTestConfig(config: String, ttl: FiniteDuration = 30.minutes): RorApiResponseWithBusinessStatus = { - call(createUpdateRorTestConfigRequest(config, ttl), new RorApiResponseWithBusinessStatus(_)) + def updateRorTestSettings(settings: String, ttl: FiniteDuration = 30.minutes): RorApiResponseWithBusinessStatus = { + call(createUpdateRorTestSettingsRequest(settings, ttl), new RorApiResponseWithBusinessStatus(_)) } - def updateRorTestConfigRaw(rawRequestBody: String): RorApiResponseWithBusinessStatus = { - call(createUpdateRorTestConfigRequest(rawRequestBody), new RorApiResponseWithBusinessStatus(_)) + def updateRorTestSettingsRaw(rawRequestBody: String): RorApiResponseWithBusinessStatus = { + call(createUpdateRorTestSettingsRequest(rawRequestBody), new RorApiResponseWithBusinessStatus(_)) } - def invalidateRorTestConfig(): RorApiResponseWithBusinessStatus = { - call(createInvalidateRorTestConfigRequest(), new RorApiResponseWithBusinessStatus(_)) + def invalidateRorTestSettings(): RorApiResponseWithBusinessStatus = { + call(createInvalidateRorTestSettingsRequest(), new RorApiResponseWithBusinessStatus(_)) } def currentRorLocalUsers: RorApiJsonResponse = { call(createProvideLocalUsersRequest(), new RorApiJsonResponse(_)) } - def reloadRorConfig(): RorApiJsonResponse = { - call(createReloadRorConfigRequest(), new RorApiJsonResponse(_)) + def reloadRorSettings(): RorApiJsonResponse = { + call(createReloadRorSettingsRequest(), new RorApiJsonResponse(_)) } def configureImpersonationMocks(payload: JSON): RorApiResponseWithBusinessStatus = { @@ -103,10 +103,10 @@ class RorApiManager(client: RestClient, call(createConfigureImpersonationMocksRequest(payload), new RorApiResponseWithBusinessStatus(_)) } - def insertInIndexConfigDirectlyToRorIndex(rorConfigIndex: String, config: String): documentManager.JsonResponse = { + def insertInIndexSettingsDirectlyToRorIndex(rorIndex: String, settings: String): documentManager.JsonResponse = { documentManager.createFirstDoc( - index = rorConfigIndex, - content = ujson.read(rorConfigIndexDocumentContentFrom(config)) + index = rorIndex, + content = ujson.read(rorSettingsIndexDocumentContentFrom(settings)) ) } @@ -127,34 +127,34 @@ class RorApiManager(client: RestClient, request } - private def createUpdateRorInIndexConfigRequest(config: String) = { + private def createUpdateRorInIndexSettingsRequest(settings: String) = { val request = new HttpPost(client.from("/_readonlyrest/admin/config")) request.addHeader("Content-Type", "application/json") - request.setEntity(new StringEntity(rorConfigIndexDocumentContentFrom(config))) + request.setEntity(new StringEntity(rorSettingsIndexDocumentContentFrom(settings))) request } - private def createUpdateRorInIndexConfigRequestFromRaw(rawRequestJson: String) = { + private def createUpdateRorInIndexSettingsRequestFromRaw(rawRequestJson: String) = { val request = new HttpPost(client.from("/_readonlyrest/admin/config")) request.addHeader("Content-Type", "application/json") request.setEntity(new StringEntity(rawRequestJson)) request } - private def createGetTestConfigRequest = { + private def createGetTestSettingsRequest = { new HttpGet(client.from("/_readonlyrest/admin/config/test")) } - private def createUpdateRorTestConfigRequest(config: String, - ttl: FiniteDuration) = { + private def createUpdateRorTestSettingsRequest(settings: String, + ttl: FiniteDuration) = { val request = new HttpPost(client.from("/_readonlyrest/admin/config/test")) request.addHeader("Content-Type", "application/json") - request.setEntity(new StringEntity(rorTestConfig(config, ttl))) + request.setEntity(new StringEntity(rorTestSettings(settings, ttl))) request } - private def createUpdateRorTestConfigRequest(rawRequestJson: String) = { + private def createUpdateRorTestSettingsRequest(rawRequestJson: String) = { val request = new HttpPost(client.from("/_readonlyrest/admin/config/test")) request.addHeader("Content-Type", "application/json") @@ -162,15 +162,15 @@ class RorApiManager(client: RestClient, request } - private def rorConfigIndexDocumentContentFrom(config: String) = { - s"""{"settings": "${escapeJava(config)}"}""" + private def rorSettingsIndexDocumentContentFrom(settings: String) = { + s"""{"settings": "${escapeJava(settings)}"}""" } - private def rorTestConfig(config: String, ttl: FiniteDuration) = { - s"""{"settings": "${escapeJava(config)}", "ttl": "${ttl.toString()}"}""" + private def rorTestSettings(settings: String, ttl: FiniteDuration) = { + s"""{"settings": "${escapeJava(settings)}", "ttl": "${ttl.toString()}"}""" } - private def createInvalidateRorTestConfigRequest() = { + private def createInvalidateRorTestSettingsRequest() = { new HttpDelete(client.from("/_readonlyrest/admin/config/test")) } @@ -178,15 +178,15 @@ class RorApiManager(client: RestClient, new HttpGet(client.from("/_readonlyrest/admin/config/test/localusers")) } - private def createGetRorFileConfigRequest() = { + private def createGetRorFileSettingsRequest() = { new HttpGet(client.from("/_readonlyrest/admin/config/file")) } - private def createGetRorInIndexConfigRequest() = { + private def createGetRorInIndexSettingsRequest() = { new HttpGet(client.from("/_readonlyrest/admin/config")) } - private def createReloadRorConfigRequest() = { + private def createReloadRorSettingsRequest() = { val request = new HttpPost(client.from("/_readonlyrest/admin/refreshconfig")) request.addHeader("Content-Type", "application/json") request @@ -224,14 +224,14 @@ class RorApiManager(client: RestClient, this } - def forceOKStatusOrConfigAlreadyLoaded(): this.type = { + def forceOKStatusOrSettingsAlreadyLoaded(): this.type = { force() - if (businessStatus === "OK" || isConfigAlreadyLoaded) { + if (businessStatus === "OK" || isSettingsAlreadyLoaded) { this } else { throw new IllegalStateException( s""" - |Expected business status 'OK' or info about already loaded config, but got:" + |Expected business status 'OK' or info about already loaded settings, but got:" | |HTTP $responseCode |${responseJson.toString()} @@ -240,7 +240,7 @@ class RorApiManager(client: RestClient, } } - private def isConfigAlreadyLoaded = { + private def isSettingsAlreadyLoaded = { businessStatus == "KO" && message.contains("already loaded") } From 3d74cfbee3f03a7eaae6a76858b7ac0db1924f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Sat, 25 Oct 2025 10:27:31 +0200 Subject: [PATCH 051/103] wip --- .../types/ResolveIndexEsRequestContext.scala | 1 - .../beshu/ror/es/IndexLevelActionFilter.scala | 19 +-- .../beshu/ror/es/ReadonlyRestPlugin.scala | 54 ++++---- .../rradmin/RRAdminActionHandler.scala | 8 +- .../actions/rradmin/RRAdminActionType.scala | 2 +- .../es/actions/rradmin/RRAdminRequest.scala | 24 ++-- .../es/actions/rradmin/RRAdminResponse.scala | 44 +++---- .../rradmin/rest/RestRRAdminAction.scala | 8 +- .../ror/es/actions/rrconfig/RRConfig.java | 65 ---------- .../actions/rrconfig/RRConfigActionType.scala | 29 ----- .../es/actions/rrconfig/RRConfigRequest.java | 56 --------- .../es/actions/rrconfig/RRConfigsRequest.java | 34 ----- .../actions/rrconfig/RRConfigsResponse.java | 47 ------- .../rrconfig/TransportRRConfigAction.scala | 117 ------------------ .../rrconfig/rest/RestRRConfigAction.scala | 56 --------- .../RestRRConfigActionResponseBuilder.scala | 65 ---------- .../RRTestSettingsActionHandler.scala} | 22 ++-- .../RRTestSettingsActionType.scala} | 14 +-- .../RRTestSettingsRequest.scala} | 34 ++--- .../RRTestSettingsResponse.scala} | 44 +++---- .../TransportRRTestSettingsAction.scala} | 18 +-- .../rest/RestRRTestSettingsAction.scala} | 16 +-- .../es/dlsfls/RoleIndexSearcherWrapper.scala | 1 - .../es/handler/AclAwareRequestFilter.scala | 2 +- .../RorNotAvailableRequestHandler.scala | 10 +- ...ice.scala => EsIndexDocumentManager.scala} | 49 ++++---- .../es/ssl/SSLNetty4HttpServerTransport.scala | 9 +- .../SSLNetty4InternodeServerTransport.scala | 14 +-- .../beshu/ror/es/utils/EsEnvProvider.scala | 5 +- 29 files changed, 195 insertions(+), 672 deletions(-) delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala delete mode 100644 es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionHandler.scala => rrtestsettings/RRTestSettingsActionHandler.scala} (69%) rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigActionType.scala => rrtestsettings/RRTestSettingsActionType.scala} (64%) rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigRequest.scala => rrtestsettings/RRTestSettingsRequest.scala} (59%) rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/RRTestConfigResponse.scala => rrtestsettings/RRTestSettingsResponse.scala} (66%) rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/TransportRRTestConfigAction.scala => rrtestsettings/TransportRRTestSettingsAction.scala} (65%) rename es92x/src/main/scala/tech/beshu/ror/es/actions/{rrtestconfig/rest/RestRRTestConfigAction.scala => rrtestsettings/rest/RestRRTestSettingsAction.scala} (71%) rename es92x/src/main/scala/tech/beshu/ror/es/services/{EsIndexJsonContentService.scala => EsIndexDocumentManager.scala} (71%) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala b/es91x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala index 50924b1f97..f96a05bb31 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/handler/request/context/types/ResolveIndexEsRequestContext.scala @@ -23,7 +23,6 @@ import org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.{Resolv import org.elasticsearch.threadpool.ThreadPool import org.joor.Reflect.* import tech.beshu.ror.accesscontrol.AccessControlList.AccessControlStaticContext -import tech.beshu.ror.accesscontrol.domain import tech.beshu.ror.accesscontrol.domain.{ClusterIndexName, RequestedIndex} import tech.beshu.ror.es.RorClusterService import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext diff --git a/es92x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala b/es92x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala index 8ecc9c9488..1b4bda121a 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/IndexLevelActionFilter.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tasks.Task import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.RemoteClusterService import org.elasticsearch.xcontent.NamedXContentRegistry +import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.audit.sink.{AuditSinkServiceCreator, DataStreamAndIndexBasedAuditSinkServiceCreator} import tech.beshu.ror.accesscontrol.domain.{Action, AuditCluster} import tech.beshu.ror.accesscontrol.matchers.UniqueIdentifierGenerator @@ -35,12 +36,12 @@ import tech.beshu.ror.boot.* import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.RorSchedulers.Implicits.mainScheduler import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.handler.AclAwareRequestFilter.{EsChain, EsContext} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext.CorrelationIdFrom import tech.beshu.ror.es.handler.response.ForbiddenResponse.createTestSettingsNotConfiguredResponse import tech.beshu.ror.es.handler.{AclAwareRequestFilter, RorNotAvailableRequestHandler} -import tech.beshu.ror.es.services.{EsIndexJsonContentService, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} +import tech.beshu.ror.es.services.{EsIndexDocumentManager, EsServerBasedRorClusterService, NodeClientBasedAuditSinkService, RestClientAuditSinkService} import tech.beshu.ror.es.utils.ThreadContextOps.createThreadContextOps import tech.beshu.ror.es.utils.{EsEnvProvider, ThreadRepo, XContentJsonParserFactory} import tech.beshu.ror.implicits.* @@ -60,20 +61,20 @@ class IndexLevelActionFilter(clusterService: ClusterService, remoteClusterServiceSupplier: Supplier[Option[RemoteClusterService]], repositoriesServiceSupplier: Supplier[Option[RepositoriesService]], esInitListener: EsInitListener, - rorEsConfig: ReadonlyRestEsConfig) - (implicit environmentConfig: EnvironmentConfig) + esConfigBasedRorSettings: EsConfigBasedRorSettings) + (implicit systemContext: SystemContext) extends ActionFilter with Logging { - private implicit val generator: UniqueIdentifierGenerator = environmentConfig.uniqueIdentifierGenerator + private implicit val generator: UniqueIdentifierGenerator = systemContext.uniqueIdentifierGenerator private val rorNotAvailableRequestHandler: RorNotAvailableRequestHandler = - new RorNotAvailableRequestHandler(rorEsConfig.bootConfig) + new RorNotAvailableRequestHandler(esConfigBasedRorSettings.boot) private val esEnv = EsEnvProvider.create(env) private val nodeName = esEnv.esNodeSettings.nodeName private val ror = ReadonlyRest.create( - new EsIndexJsonContentService(client), + new EsIndexDocumentManager(client), auditSinkServiceCreator, esEnv, ) @@ -106,7 +107,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def createService(cluster: AuditCluster): IndexBasedAuditSinkService & DataStreamBasedAuditSinkService = { cluster match { case AuditCluster.LocalAuditCluster => - new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry), threadPool)(using environmentConfig.clock) + new NodeClientBasedAuditSinkService(client, new XContentJsonParserFactory(xContentRegistry), threadPool)(using systemContext.clock) case remote: AuditCluster.RemoteAuditCluster => RestClientAuditSinkService.create(remote) } @@ -220,7 +221,7 @@ class IndexLevelActionFilter(clusterService: ClusterService, private def startRorInstance() = { val startResult = for { _ <- esInitListener.waitUntilReady - result <- ror.start() + result <- ror.start(esConfigBasedRorSettings) } yield result startResult.runAsync { case Right(Right(instance)) => diff --git a/es92x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala b/es92x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala index 5c515491e8..f5425974d8 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/ReadonlyRestPlugin.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es +import cats.implicits.* import monix.execution.Scheduler import monix.execution.schedulers.CanBlock import org.elasticsearch.ElasticsearchException @@ -35,8 +36,8 @@ import org.elasticsearch.http.{HttpPreRequest, HttpServerTransport} import org.elasticsearch.index.IndexModule import org.elasticsearch.index.mapper.IgnoredFieldMapper import org.elasticsearch.indices.breaker.CircuitBreakerService -import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.plugins.* +import org.elasticsearch.plugins.ActionPlugin.ActionHandler import org.elasticsearch.repositories.RepositoriesService import org.elasticsearch.rest.{RestController, RestHandler} import org.elasticsearch.telemetry.TelemetryProvider @@ -46,26 +47,25 @@ import org.elasticsearch.transport.{Transport, TransportInterceptor} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.boot.{EsInitListener, SecurityProviderConfiguratorForFips} import tech.beshu.ror.buildinfo.LogPluginBuildInfoMessage -import tech.beshu.ror.configuration.{EnvironmentConfig, ReadonlyRestEsConfig} -import tech.beshu.ror.constants +import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.es.actions.rradmin.rest.RestRRAdminAction import tech.beshu.ror.es.actions.rradmin.{RRAdminActionType, TransportRRAdminAction} import tech.beshu.ror.es.actions.rrauditevent.rest.RestRRAuditEventAction import tech.beshu.ror.es.actions.rrauditevent.{RRAuditEventActionType, TransportRRAuditEventAction} import tech.beshu.ror.es.actions.rrauthmock.rest.RestRRAuthMockAction import tech.beshu.ror.es.actions.rrauthmock.{RRAuthMockActionType, TransportRRAuthMockAction} -import tech.beshu.ror.es.actions.rrconfig.rest.RestRRConfigAction -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, TransportRRConfigAction} import tech.beshu.ror.es.actions.rrmetadata.rest.RestRRUserMetadataAction import tech.beshu.ror.es.actions.rrmetadata.{RRUserMetadataActionType, TransportRRUserMetadataAction} -import tech.beshu.ror.es.actions.rrtestconfig.rest.RestRRTestConfigAction -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, TransportRRTestConfigAction} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, TransportRRTestSettingsAction} +import tech.beshu.ror.es.actions.rrtestsettings.rest.RestRRTestSettingsAction import tech.beshu.ror.es.actions.wrappers._cat.{RorWrappedCatActionType, TransportRorWrappedCatAction} import tech.beshu.ror.es.dlsfls.RoleIndexSearcherWrapper import tech.beshu.ror.es.ssl.{SSLNetty4HttpServerTransport, SSLNetty4InternodeServerTransport} import tech.beshu.ror.es.utils.{ChannelInterceptingRestHandlerDecorator, EsEnvProvider, EsPatchVerifier, RemoteClusterServiceSupplier} +import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SetOnce +import tech.beshu.ror.{SystemContext, constants} import java.nio.file.Path import java.util @@ -96,20 +96,20 @@ class ReadonlyRestPlugin(s: Settings, p: Path) Netty4Utils.setAvailableProcessors(EsExecutors.NODE_PROCESSORS_SETTING.get(s).roundDown()) } - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default + private implicit val systemContext: SystemContext = SystemContext.default private val environment = new Environment(s, p) private val timeout: FiniteDuration = 10 seconds - private val rorEsConfig = ReadonlyRestEsConfig - .load(EsEnvProvider.create(environment)) - .map(_.fold(e => throw new ElasticsearchException(e.message), identity)) + private val esConfigBasedRorSettings = EsConfigBasedRorSettings + .from(EsEnvProvider.create(environment)) + .map(_.fold(e => throw new ElasticsearchException(e.show), identity)) .runSyncUnsafe(timeout)(Scheduler.global, CanBlock.permit) private val esInitListener = new EsInitListener private val groupFactory = new SetOnce[SharedGroupFactory] private var ilaf: IndexLevelActionFilter = _ - SecurityProviderConfiguratorForFips.configureIfRequired(rorEsConfig.fipsConfig) + esConfigBasedRorSettings.ssl.foreach(SecurityProviderConfiguratorForFips.configureIfRequired) override def createComponents(services: Plugin.PluginServices): util.Collection[_] = { doPrivileged { @@ -126,7 +126,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) new RemoteClusterServiceSupplier(client), () => Some(repositoriesServiceSupplier.get()), esInitListener, - rorEsConfig + esConfigBasedRorSettings ) } List.empty[AnyRef].asJava @@ -160,14 +160,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) perRequestThreadContext: BiConsumer[HttpPreRequest, ThreadContext], clusterSettings: ClusterSettings, telemetryProvider: TelemetryProvider): util.Map[String, Supplier[HttpServerTransport]] = { - rorEsConfig - .sslConfig - .externalSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.externalSsl) + .map { ssl => "ssl_netty4" -> new Supplier[HttpServerTransport] { - override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), telemetryProvider, rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): HttpServerTransport = new SSLNetty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, ssl, clusterSettings, getSharedGroupFactory(settings), telemetryProvider) } - ) + } .toMap .asJava } @@ -178,14 +177,13 @@ class ReadonlyRestPlugin(s: Settings, p: Path) circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService): util.Map[String, Supplier[Transport]] = { - rorEsConfig - .sslConfig - .interNodeSsl - .map(ssl => + esConfigBasedRorSettings + .ssl.flatMap(_.internodeSsl) + .map { ssl => "ror_ssl_internode" -> new Supplier[Transport] { - override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings), rorEsConfig.fipsConfig.isSslFipsCompliant) + override def get(): Transport = new SSLNetty4InternodeServerTransport(settings, threadPool, pageCacheRecycler, circuitBreakerService, namedWriteableRegistry, networkService, ssl, getSharedGroupFactory(settings)) } - ) + } .toMap .asJava } @@ -203,8 +201,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[ActionPlugin.ActionHandler]( new ActionHandler(RRAdminActionType.instance, classOf[TransportRRAdminAction]), new ActionHandler(RRAuthMockActionType.instance, classOf[TransportRRAuthMockAction]), - new ActionHandler(RRTestConfigActionType.instance, classOf[TransportRRTestConfigAction]), - new ActionHandler(RRConfigActionType.instance, classOf[TransportRRConfigAction]), + new ActionHandler(RRTestSettingsActionType.instance, classOf[TransportRRTestSettingsAction]), new ActionHandler(RRUserMetadataActionType.instance, classOf[TransportRRUserMetadataAction]), new ActionHandler(RRAuditEventActionType.instance, classOf[TransportRRAuditEventAction]), // wrappers @@ -226,8 +223,7 @@ class ReadonlyRestPlugin(s: Settings, p: Path) List[RestHandler]( new RestRRAdminAction(), new RestRRAuthMockAction(), - new RestRRTestConfigAction(), - new RestRRConfigAction(nodesInCluster), + new RestRRTestSettingsAction(), new RestRRUserMetadataAction(), new RestRRAuditEventAction() ).asJava diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala index 6babc712b9..3165661004 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionHandler.scala @@ -21,7 +21,7 @@ import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi.ConfigResponse +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged @@ -42,11 +42,11 @@ class RRAdminActionHandler extends Logging { } } case None => - listener.onFailure(new Exception("Config API is not available")) + listener.onFailure(new Exception("ROR Settings API is not available")) } } - private def handle(result: Either[Throwable, ConfigResponse], + private def handle(result: Either[Throwable, MainSettingsResponse], listener: ActionListener[RRAdminResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => @@ -57,5 +57,5 @@ class RRAdminActionHandler extends Logging { } private def getApi = - RorInstanceSupplier.get().map(_.configApi) + RorInstanceSupplier.get().map(_.mainSettingsApi) } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala index 12bfaf5f7b..45c9923dc5 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminActionType.scala @@ -23,7 +23,7 @@ import tech.beshu.ror.accesscontrol.domain.Action.RorAction class RRAdminActionType extends ActionType[RRAdminResponse](RRAdminActionType.name) object RRAdminActionType { - val name: String = RorAction.RorOldConfigAction.value + val name: String = RorAction.RorRefreshSettingsAction.value val instance = new RRAdminActionType() case object RRAdminActionCannotBeTransported extends Exception def exceptionReader[A]: Writeable.Reader[A] = diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala index ac36f49056..7240997d62 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminRequest.scala @@ -20,15 +20,15 @@ import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.ConfigApi +import tech.beshu.ror.api.MainSettingsApi import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRAdminRequest(adminApiRequest: ConfigApi.ConfigRequest, +class RRAdminRequest(adminApiRequest: MainSettingsApi.MainSettingsRequest, esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - val getAdminRequest: ConfigApi.ConfigRequest = adminApiRequest + val getAdminRequest: MainSettingsApi.MainSettingsRequest = adminApiRequest lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null @@ -38,19 +38,19 @@ object RRAdminRequest { def createFrom(request: RestRequest): RRAdminRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.FORCE_RELOAD_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.ForceReload - case (constants.PROVIDE_FILE_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideFileConfig - case (constants.PROVIDE_INDEX_CONFIG_PATH, GET) => - ConfigApi.ConfigRequest.Type.ProvideIndexConfig - case (constants.UPDATE_INDEX_CONFIG_PATH, POST) => - ConfigApi.ConfigRequest.Type.UpdateIndexConfig + case (constants.FORCE_RELOAD_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.ForceReload + case (constants.PROVIDE_FILE_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideFileSettings + case (constants.PROVIDE_INDEX_SETTINGS_PATH, GET) => + MainSettingsApi.MainSettingsRequest.Type.ProvideIndexSettings + case (constants.UPDATE_INDEX_SETTINGS_PATH, POST) => + MainSettingsApi.MainSettingsRequest.Type.UpdateIndexSettings case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } new RRAdminRequest( - new ConfigApi.ConfigRequest(requestType, request.content.utf8ToString), + new MainSettingsApi.MainSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala index 003fddfe63..42ef512263 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/RRAdminResponse.scala @@ -20,34 +20,34 @@ import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.ConfigApi -import tech.beshu.ror.api.ConfigApi.ConfigResponse.* -import tech.beshu.ror.api.ConfigApi.* +import tech.beshu.ror.api.MainSettingsApi +import tech.beshu.ror.api.MainSettingsApi.MainSettingsResponse.* +import tech.beshu.ror.api.MainSettingsApi.* import tech.beshu.ror.es.utils.StatusToXContentObject -class RRAdminResponse(response: ConfigApi.ConfigResponse) +class RRAdminResponse(response: MainSettingsApi.MainSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case forceReloadConfig: ConfigResponse.ForceReloadConfig => forceReloadConfig match { - case ForceReloadConfig.Success(message) => addResponseJson(builder, response.status, message) - case ForceReloadConfig.Failure(message) => addResponseJson(builder, response.status, message) + case forceReloadSettings: MainSettingsResponse.ForceReloadMainSettings => forceReloadSettings match { + case ForceReloadMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case ForceReloadMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideIndexConfig: ConfigResponse.ProvideIndexConfig => provideIndexConfig match { - case ProvideIndexConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideIndexConfig.ConfigNotFound(message) => addResponseJson(builder, response.status, message) - case ProvideIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideIndexSettings: MainSettingsResponse.ProvideIndexMainSettings => provideIndexSettings match { + case ProvideIndexMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideIndexMainSettings.MainSettingsNotFound(message) => addResponseJson(builder, response.status, message) + case ProvideIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case provideFileConfig: ConfigResponse.ProvideFileConfig => provideFileConfig match { - case ProvideFileConfig.Config(rawConfig) => addResponseJson(builder, response.status, rawConfig) - case ProvideFileConfig.Failure(message) => addResponseJson(builder, response.status, message) + case provideFileSettings: MainSettingsResponse.ProvideFileMainSettings => provideFileSettings match { + case ProvideFileMainSettings.MainSettings(rawSettings) => addResponseJson(builder, response.status, rawSettings) + case ProvideFileMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case updateIndexConfig: ConfigResponse.UpdateIndexConfig => updateIndexConfig match { - case UpdateIndexConfig.Success(message) => addResponseJson(builder, response.status, message) - case UpdateIndexConfig.Failure(message) => addResponseJson(builder, response.status, message) + case updateIndexSettings: MainSettingsResponse.UpdateIndexMainSettings => updateIndexSettings match { + case UpdateIndexMainSettings.Success(message) => addResponseJson(builder, response.status, message) + case UpdateIndexMainSettings.Failure(message) => addResponseJson(builder, response.status, message) } - case failure: ConfigResponse.Failure => failure match { + case failure: MainSettingsResponse.Failure => failure match { case Failure.BadRequest(message) => addResponseJson(builder, response.status, message) } } @@ -58,10 +58,10 @@ class RRAdminResponse(response: ConfigApi.ConfigResponse) override def status: RestStatus = { response match { - case _: ForceReloadConfig => RestStatus.OK - case _: ProvideIndexConfig => RestStatus.OK - case _: ProvideFileConfig => RestStatus.OK - case _: UpdateIndexConfig => RestStatus.OK + case _: ForceReloadMainSettings => RestStatus.OK + case _: ProvideIndexMainSettings => RestStatus.OK + case _: ProvideFileMainSettings => RestStatus.OK + case _: UpdateIndexMainSettings => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala index 1ecc29436c..7770420170 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rradmin/rest/RestRRAdminAction.scala @@ -32,10 +32,10 @@ class RestRRAdminAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(POST, constants.FORCE_RELOAD_CONFIG_PATH), - new Route(GET, constants.PROVIDE_FILE_CONFIG_PATH), - new Route(GET, constants.PROVIDE_INDEX_CONFIG_PATH), - new Route(POST, constants.UPDATE_INDEX_CONFIG_PATH), + new Route(POST, constants.FORCE_RELOAD_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_FILE_SETTINGS_PATH), + new Route(GET, constants.PROVIDE_INDEX_SETTINGS_PATH), + new Route(POST, constants.UPDATE_INDEX_SETTINGS_PATH), ).asJava override val getName: String = "ror-admin-handler" diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java deleted file mode 100644 index 21317a9d83..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodeResponse; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.injection.guice.Inject; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfig; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigSerializer; - -import java.io.IOException; - -public class RRConfig extends BaseNodeResponse { - private final NodeConfig nodeConfig; - - @Inject - public RRConfig(StreamInput in) throws IOException { - super(in); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - public RRConfig(DiscoveryNode discoveryNode, NodeConfig nodeConfig) { - super(discoveryNode); - this.nodeConfig = nodeConfig; - } - - public RRConfig(DiscoveryNode discoveryNode, StreamInput in) throws IOException { - super(discoveryNode); - this.nodeConfig = NodeConfigSerializer.parse(in.readString()); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(NodeConfigSerializer.serialize(nodeConfig)); - } - - public NodeConfig getNodeConfig() { - return nodeConfig; - } - - @Override - public String toString() { - return "RRConfig{" + - "nodeConfig=" + nodeConfig + ", " + - "discoveryNode=" + getNode() + - '}'; - } -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala deleted file mode 100644 index 942897ce23..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigActionType.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import org.elasticsearch.action.ActionType -import org.elasticsearch.common.io.stream.Writeable -import tech.beshu.ror.accesscontrol.domain.Action.RorAction - -class RRConfigActionType extends ActionType[RRConfigsResponse](RRConfigActionType.name) - -object RRConfigActionType { - val name: String = RorAction.RorConfigAction.value - val instance = new RRConfigActionType - val reader: Writeable.Reader[RRConfigsResponse] = new RRConfigsResponse(_) -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java deleted file mode 100644 index 426641ac63..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigRequest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Objects; - -public class RRConfigRequest extends ActionRequest { - - private final NodeConfigRequest nodeConfigRequest; - - public RRConfigRequest(NodeConfigRequest nodeConfigRequest) { - this.nodeConfigRequest = Objects.requireNonNull(nodeConfigRequest); - } - - public RRConfigRequest(StreamInput in) throws IOException { - super(in); - this.nodeConfigRequest = NodeConfigRequestSerializer.parse(in.readString()); - } - - public NodeConfigRequest getNodeConfigRequest() { - return nodeConfigRequest; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); // header - out.writeString(NodeConfigRequestSerializer.serialize(nodeConfigRequest)); - } - - @Override - public ActionRequestValidationException validate() { - return null; - } -} \ No newline at end of file diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java deleted file mode 100644 index 0db5eda205..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.support.nodes.BaseNodesRequest; -import org.elasticsearch.cluster.node.DiscoveryNode; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import tech.beshu.ror.configuration.loader.distributed.NodeConfigRequest; -import tech.beshu.ror.configuration.loader.distributed.internode.NodeConfigRequestSerializer; - -import java.io.IOException; -import java.util.Arrays; - -public class RRConfigsRequest extends BaseNodesRequest { - - public RRConfigsRequest(DiscoveryNode... concreteNodes) { - super(concreteNodes); - } -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java deleted file mode 100644 index 28a9fbeafc..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/RRConfigsResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig; - -import org.elasticsearch.action.FailedNodeException; -import org.elasticsearch.action.support.nodes.BaseNodesResponse; -import org.elasticsearch.cluster.ClusterName; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; - -import java.io.IOException; -import java.util.List; - -public class RRConfigsResponse extends BaseNodesResponse { - - protected RRConfigsResponse(StreamInput in) throws IOException { - super(in); - } - - public RRConfigsResponse(ClusterName clusterName, List nodes, List failures) { - super(clusterName, nodes, failures); - } - - @Override - protected List readNodesFrom(StreamInput in) throws IOException { - return in.readCollectionAsList(RRConfig::new); - } - - @Override - protected void writeNodesTo(StreamOutput out, List nodes) throws IOException { - out.writeCollection(nodes); - } -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala deleted file mode 100644 index c0aba7ad0b..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/TransportRRConfigAction.scala +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig - -import cats.implicits.* -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.action.support.ActionFilters -import org.elasticsearch.action.support.nodes.TransportNodesAction -import org.elasticsearch.cluster.node.DiscoveryNode -import org.elasticsearch.cluster.service.ClusterService -import org.elasticsearch.common.io.stream.{StreamInput, Writeable} -import org.elasticsearch.env.Environment -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.tasks.Task -import org.elasticsearch.threadpool.ThreadPool -import org.elasticsearch.transport.TransportService -import tech.beshu.ror.configuration.EnvironmentConfig -import tech.beshu.ror.configuration.loader.* -import tech.beshu.ror.configuration.loader.distributed.{NodeConfig, NodeConfigRequest, RawRorConfigLoadingAction, Timeout} -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.services.EsIndexJsonContentService -import tech.beshu.ror.es.utils.EsEnvProvider -import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged - -import java.util -import java.util.concurrent.Executor -import scala.annotation.unused -import scala.concurrent.duration.* -import scala.language.postfixOps - -class TransportRRConfigAction(actionName: String, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: IndexJsonContentService, - nodeRequest: Writeable.Reader[RRConfigRequest], - executor: Executor, - @unused constructorDiscriminator: Unit) - extends TransportNodesAction[RRConfigsRequest, RRConfigsResponse, RRConfigRequest, RRConfig, Void]( - actionName, - clusterService, - transportService, - actionFilters, - nodeRequest, - executor - ) { - - import tech.beshu.ror.boot.RorSchedulers.Implicits.rorRestApiScheduler - - private implicit val environmentConfig: EnvironmentConfig = EnvironmentConfig.default - - @Inject - def this(actionName: String, - threadPool: ThreadPool, - clusterService: ClusterService, - transportService: TransportService, - actionFilters: ActionFilters, - env: Environment, - indexContentProvider: EsIndexJsonContentService, - ) = - this( - RRConfigActionType.name, - clusterService, - transportService, - actionFilters, - env, - indexContentProvider, - new RRConfigRequest(_), - threadPool.executor(ThreadPool.Names.GENERIC), - () - ) - - override def newResponse(request: RRConfigsRequest, responses: util.List[RRConfig], failures: util.List[FailedNodeException]): RRConfigsResponse = { - new RRConfigsResponse(clusterService.getClusterName, responses, failures) - } - - override def newNodeResponse(streamInput: StreamInput, discoveryNode: DiscoveryNode): RRConfig = { - new RRConfig(discoveryNode, streamInput) - } - - override def newNodeRequest(request: RRConfigsRequest): RRConfigRequest = - new RRConfigRequest(new NodeConfigRequest(NodeConfigRequest.defaultTimeout)) - - private def loadConfig() = doPrivileged { - RawRorConfigLoadingAction - .loadFromIndex(EsEnvProvider.create(env), indexContentProvider) - .map(_.map(_.map(_.raw))) - } - - override def nodeOperation(request: RRConfigRequest, task: Task): RRConfig = { - val nodeRequest = request.getNodeConfigRequest - val nodeResponse = - loadConfig() - .runSyncUnsafe(toFiniteDuration(nodeRequest.timeout)) - new RRConfig(clusterService.localNode(), NodeConfig(nodeResponse)) - } - - private def toFiniteDuration(timeout: Timeout): FiniteDuration = timeout.nanos nanos - -} - - diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala deleted file mode 100644 index 59203f11f5..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigAction.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import org.elasticsearch.client.internal.node.NodeClient -import org.elasticsearch.cluster.node.DiscoveryNodes -import org.elasticsearch.injection.guice.Inject -import org.elasticsearch.rest.* -import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer -import org.elasticsearch.rest.RestHandler.Route -import org.elasticsearch.rest.RestRequest.Method.GET -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.NodeId -import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrconfig.{RRConfigActionType, RRConfigsRequest} - -import java.util -import java.util.function.Supplier -import scala.jdk.CollectionConverters.* - -@Inject -class RestRRConfigAction(nodesInCluster: Supplier[DiscoveryNodes]) - extends BaseRestHandler { - - override def routes(): util.List[Route] = List( - new Route(GET, constants.MANAGE_ROR_CONFIG_PATH), - ).asJava - - override val getName: String = "ror-config-handler" - - override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = { - channel => - client.execute( - new RRConfigActionType, - new RRConfigsRequest(nodes.toArray: _*), - new RestRRConfigActionResponseBuilder(NodeId(client.getLocalNodeId), channel) - ) - } - - private def nodes = - nodesInCluster.get().asScala.toList - -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala deleted file mode 100644 index 5f1ba63898..0000000000 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrconfig/rest/RestRRConfigActionResponseBuilder.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of ReadonlyREST. - * - * ReadonlyREST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ReadonlyREST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ - */ -package tech.beshu.ror.es.actions.rrconfig.rest - -import java.util.concurrent.TimeoutException - -import org.elasticsearch.action.FailedNodeException -import org.elasticsearch.xcontent.XContentBuilder -import org.elasticsearch.rest.action.RestBuilderListener -import org.elasticsearch.rest.{RestChannel, RestResponse, RestStatus} -import org.elasticsearch.transport.ActionNotFoundTransportException -import tech.beshu.ror.configuration.loader.distributed.NodesResponse -import tech.beshu.ror.configuration.loader.distributed.NodesResponse.{NodeError, NodeId, NodeResponse} -import tech.beshu.ror.es.actions.rrconfig.{RRConfig, RRConfigsResponse} - -import scala.jdk.CollectionConverters.* - -final class RestRRConfigActionResponseBuilder(localNode: NodeId, channel: RestChannel) - extends RestBuilderListener[RRConfigsResponse](channel) { - - override def buildResponse(response: RRConfigsResponse, builder: XContentBuilder): RestResponse = { - val nodeResponse = createNodesResponse(response) - new RestResponse(RestStatus.OK, nodeResponse.toJson) - } - - private def createNodesResponse(response: RRConfigsResponse) = - NodesResponse.create( - localNode = localNode, - responses = response.getNodes.asScala.toList.map(createNodeResponse), - failures = response.failures().asScala.toList.map(createNodeError), - ) - - private def createNodeResponse(config: RRConfig) = { - NodeResponse(NodeId(config.getNode.getId), config.getNodeConfig.loadedConfig) - } - - private def createNodeError(failedNodeException: FailedNodeException) = { - NodeError(NodeId(failedNodeException.nodeId()), createCause(failedNodeException)) - } - - private def createCause(failedNodeException: FailedNodeException): NodeError.Cause = { - failedNodeException.getRootCause match { - case _: TimeoutException => - NodeError.Timeout - case _: ActionNotFoundTransportException => - NodeError.RorConfigActionNotFound - case _ => - NodeError.Unknown(failedNodeException.getDetailedMessage) - } - } -} diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala similarity index 69% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala index aa8bb31e67..3fe2540c1b 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionHandler.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionHandler.scala @@ -14,48 +14,48 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import cats.implicits.toShow import monix.execution.Scheduler import org.apache.logging.log4j.scala.Logging import org.elasticsearch.action.ActionListener import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse import tech.beshu.ror.boot.RorSchedulers import tech.beshu.ror.implicits.* import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.RorInstanceSupplier -class RRTestConfigActionHandler extends Logging { +class RRTestSettingsActionHandler extends Logging { private implicit val rorRestApiScheduler: Scheduler = RorSchedulers.restApiScheduler - def handle(request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + def handle(request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { getApi match { case Some(api) => doPrivileged { implicit val requestId: RequestId = request.requestContextId api - .call(request.getTestConfigRequest) + .call(request.getTestSettingsRequest) .runAsync { result => handle(result, listener) } } case None => - listener.onFailure(new Exception("TestConfig API is not available")) + listener.onFailure(new Exception("ROR Test Settings API is not available")) } } - private def handle(result: Either[Throwable, TestConfigResponse], - listener: ActionListener[RRTestConfigResponse]) + private def handle(result: Either[Throwable, TestSettingsResponse], + listener: ActionListener[RRTestSettingsResponse]) (implicit requestId: RequestId): Unit = result match { case Right(response) => - listener.onResponse(new RRTestConfigResponse(response)) + listener.onResponse(new RRTestSettingsResponse(response)) case Left(ex) => - logger.error(s"[${requestId.show}] RRTestConfig internal error", ex) + logger.error(s"[${requestId.show}] Internal error", ex) listener.onFailure(new Exception(ex)) } private def getApi = - RorInstanceSupplier.get().map(_.testConfigApi) + RorInstanceSupplier.get().map(_.testSettingsApi) } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala similarity index 64% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala index 35dfdaaa74..2ed1b97248 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigActionType.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsActionType.scala @@ -14,20 +14,20 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionType import org.elasticsearch.common.io.stream.Writeable import tech.beshu.ror.accesscontrol.domain.Action.RorAction -class RRTestConfigActionType extends ActionType[RRTestConfigResponse](RRTestConfigActionType.name) +class RRTestSettingsActionType extends ActionType[RRTestSettingsResponse](RRTestSettingsActionType.name) -object RRTestConfigActionType { - val name: String = RorAction.RorTestConfigAction.value - val instance = new RRTestConfigActionType() +object RRTestSettingsActionType { + val name: String = RorAction.RorTestSettingsAction.value + val instance = new RRTestSettingsActionType() - case object RRTestConfigActionCannotBeTransported extends Exception + case object RRTestSettingsActionCannotBeTransported extends Exception - private [rrtestconfig] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestConfigActionCannotBeTransported + private [rrtestsettings] def exceptionReader[A]: Writeable.Reader[A] = _ => throw RRTestSettingsActionCannotBeTransported } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala similarity index 59% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala index d4574bf654..c690c5ecfd 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigRequest.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsRequest.scala @@ -14,45 +14,45 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.{ActionRequest, ActionRequestValidationException} import org.elasticsearch.rest.RestRequest import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import tech.beshu.ror.accesscontrol.domain.RequestId -import tech.beshu.ror.api.{RorApiRequest, TestConfigApi} +import tech.beshu.ror.api.{RorApiRequest, TestSettingsApi} import tech.beshu.ror.constants import tech.beshu.ror.es.actions.RorActionRequest import tech.beshu.ror.utils.ScalaOps.* -class RRTestConfigRequest(testConfigApiRequest: TestConfigApi.TestConfigRequest, - esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { +class RRTestSettingsRequest(request: TestSettingsApi.TestSettingsRequest, + esRestRequest: RestRequest) extends ActionRequest with RorActionRequest { - def getTestConfigRequest: RorApiRequest[TestConfigApi.TestConfigRequest] = - RorApiRequest(testConfigApiRequest, loggerUser) + def getTestSettingsRequest: RorApiRequest[TestSettingsApi.TestSettingsRequest] = + RorApiRequest(request, loggerUser) lazy val requestContextId: RequestId = RequestId(s"${esRestRequest.hashCode()}-${this.hashCode()}") override def validate(): ActionRequestValidationException = null } -object RRTestConfigRequest { +object RRTestSettingsRequest { - def createFrom(request: RestRequest): RRTestConfigRequest = { + def createFrom(request: RestRequest): RRTestSettingsRequest = { val requestType = (request.uri().addTrailingSlashIfNotPresent(), request.method()) match { - case (constants.PROVIDE_TEST_CONFIG_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideTestConfig - case (constants.DELETE_TEST_CONFIG_PATH, DELETE) => - TestConfigApi.TestConfigRequest.Type.InvalidateTestConfig - case (constants.UPDATE_TEST_CONFIG_PATH, POST) => - TestConfigApi.TestConfigRequest.Type.UpdateTestConfig + case (constants.PROVIDE_TEST_SETTINGS_PATH, GET) => + TestSettingsApi.TestSettingsRequest.Type.ProvideTestSettings + case (constants.DELETE_TEST_SETTINGS_PATH, DELETE) => + TestSettingsApi.TestSettingsRequest.Type.InvalidateTestSettings + case (constants.UPDATE_TEST_SETTINGS_PATH, POST) => + TestSettingsApi.TestSettingsRequest.Type.UpdateTestSettings case (constants.PROVIDE_LOCAL_USERS_PATH, GET) => - TestConfigApi.TestConfigRequest.Type.ProvideLocalUsers + TestSettingsApi.TestSettingsRequest.Type.ProvideLocalUsers case (unknownUri, unknownMethod) => throw new IllegalStateException(s"Unknown request: $unknownMethod $unknownUri") } - new RRTestConfigRequest( - TestConfigApi.TestConfigRequest(requestType, request.content.utf8ToString), + new RRTestSettingsRequest( + TestSettingsApi.TestSettingsRequest(requestType, request.content.utf8ToString), request ) } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala similarity index 66% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala index d2c63676b7..ad72c8e5cf 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/RRTestConfigResponse.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/RRTestSettingsResponse.scala @@ -14,35 +14,35 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionResponse import org.elasticsearch.common.io.stream.StreamOutput import tech.beshu.ror.es.utils.StatusToXContentObject import org.elasticsearch.rest.RestStatus import org.elasticsearch.xcontent.{ToXContent, XContentBuilder} -import tech.beshu.ror.api.TestConfigApi -import tech.beshu.ror.api.TestConfigApi.TestConfigResponse.* +import tech.beshu.ror.api.TestSettingsApi +import tech.beshu.ror.api.TestSettingsApi.TestSettingsResponse.* import java.time.ZoneOffset -class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) +class RRTestSettingsResponse(response: TestSettingsApi.TestSettingsResponse) extends ActionResponse with StatusToXContentObject { override def toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder = { response match { - case provideConfigResponse: ProvideTestConfig => provideConfigResponse match { - case res: ProvideTestConfig.CurrentTestSettings => currentConfigJson(builder, res) - case ProvideTestConfig.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) - case res: ProvideTestConfig.TestSettingsInvalidated => invalidatedConfigJson(builder, res) + case provideSettingsResponse: ProvideTestSettings => provideSettingsResponse match { + case res: ProvideTestSettings.CurrentTestSettings => currentSettingsJson(builder, res) + case ProvideTestSettings.TestSettingsNotConfigured(message) => addResponseJson(builder, response.status, message) + case res: ProvideTestSettings.TestSettingsInvalidated => invalidatedSettingsJson(builder, res) } - case updateConfigResponse: UpdateTestConfig => updateConfigResponse match { - case res: UpdateTestConfig.SuccessResponse => updateConfigSuccessResponseJson(builder, res) - case UpdateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case updateSettingsResponse: UpdateTestSettings => updateSettingsResponse match { + case res: UpdateTestSettings.SuccessResponse => updateSettingsSuccessResponseJson(builder, res) + case UpdateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } - case invalidateConfigResponse: InvalidateTestConfig => invalidateConfigResponse match { - case InvalidateTestConfig.SuccessResponse(message) => addResponseJson(builder, response.status, message) - case InvalidateTestConfig.FailedResponse(message) => addResponseJson(builder, response.status, message) + case invalidateSettingsResponse: InvalidateTestSettings => invalidateSettingsResponse match { + case InvalidateTestSettings.SuccessResponse(message) => addResponseJson(builder, response.status, message) + case InvalidateTestSettings.FailedResponse(message) => addResponseJson(builder, response.status, message) } case provideUsersResponse: ProvideLocalUsers => provideUsersResponse match { case res: ProvideLocalUsers.SuccessResponse => provideLocalUsersJson(builder, res) @@ -59,9 +59,9 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) override def writeTo(out: StreamOutput): Unit = () override def status: RestStatus = response match { - case _: ProvideTestConfig => RestStatus.OK - case _: UpdateTestConfig => RestStatus.OK - case _: InvalidateTestConfig => RestStatus.OK + case _: ProvideTestSettings => RestStatus.OK + case _: UpdateTestSettings => RestStatus.OK + case _: InvalidateTestSettings => RestStatus.OK case _: ProvideLocalUsers => RestStatus.OK case failure: Failure => failure match { case Failure.BadRequest(_) => RestStatus.BAD_REQUEST @@ -75,26 +75,26 @@ class RRTestConfigResponse(response: TestConfigApi.TestConfigResponse) builder.endObject } - private def currentConfigJson(builder: XContentBuilder, response: ProvideTestConfig.CurrentTestSettings): Unit = { + private def currentSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.CurrentTestSettings): Unit = { builder.startObject builder.field("status", response.status) builder.field("ttl", response.ttl.toString()) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("valid_to", response.validTo.atOffset(ZoneOffset.UTC).toString) warningsJson(builder, response.warnings) builder.endObject } - private def invalidatedConfigJson(builder: XContentBuilder, response: ProvideTestConfig.TestSettingsInvalidated): Unit = { + private def invalidatedSettingsJson(builder: XContentBuilder, response: ProvideTestSettings.TestSettingsInvalidated): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) - builder.field("settings", response.settings.raw) + builder.field("settings", response.settings.rawYaml) builder.field("ttl", response.ttl.toString()) builder.endObject } - private def updateConfigSuccessResponseJson(builder: XContentBuilder, response: UpdateTestConfig.SuccessResponse): Unit = { + private def updateSettingsSuccessResponseJson(builder: XContentBuilder, response: UpdateTestSettings.SuccessResponse): Unit = { builder.startObject builder.field("status", response.status) builder.field("message", response.message) diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala similarity index 65% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala index 2d936937d3..d72dc8acfe 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/TransportRRTestConfigAction.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/TransportRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig +package tech.beshu.ror.es.actions.rrtestsettings import org.elasticsearch.action.ActionListener import org.elasticsearch.action.support.{ActionFilters, HandledTransportAction} @@ -26,12 +26,12 @@ import org.elasticsearch.transport.TransportService import java.util.concurrent.Executor import scala.annotation.unused -class TransportRRTestConfigAction(transportService: TransportService, - actionFilters: ActionFilters, - executor: Executor, - @unused constructorDiscriminator: Unit) - extends HandledTransportAction[RRTestConfigRequest, RRTestConfigResponse]( - RRTestConfigActionType.name, transportService, actionFilters, RRTestConfigActionType.exceptionReader[RRTestConfigRequest], executor +class TransportRRTestSettingsAction(transportService: TransportService, + actionFilters: ActionFilters, + executor: Executor, + @unused constructorDiscriminator: Unit) + extends HandledTransportAction[RRTestSettingsRequest, RRTestSettingsResponse]( + RRTestSettingsActionType.name, transportService, actionFilters, RRTestSettingsActionType.exceptionReader[RRTestSettingsRequest], executor ) { @Inject @@ -40,9 +40,9 @@ class TransportRRTestConfigAction(transportService: TransportService, threadPool: ThreadPool) = this(transportService, actionFilters, threadPool.executor(ThreadPool.Names.GENERIC), ()) - private val handler = new RRTestConfigActionHandler() + private val handler = new RRTestSettingsActionHandler() - override def doExecute(task: Task, request: RRTestConfigRequest, listener: ActionListener[RRTestConfigResponse]): Unit = { + override def doExecute(task: Task, request: RRTestSettingsRequest, listener: ActionListener[RRTestSettingsResponse]): Unit = { handler.handle(request, listener) } } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala similarity index 71% rename from es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala rename to es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala index c2da8cabe9..500846af8d 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestconfig/rest/RestRRTestConfigAction.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/actions/rrtestsettings/rest/RestRRTestSettingsAction.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.es.actions.rrtestconfig.rest +package tech.beshu.ror.es.actions.rrtestsettings.rest import org.elasticsearch.client.internal.node.NodeClient import org.elasticsearch.rest.BaseRestHandler.RestChannelConsumer @@ -22,29 +22,29 @@ import org.elasticsearch.rest.RestHandler.Route import org.elasticsearch.rest.RestRequest.Method.{DELETE, GET, POST} import org.elasticsearch.rest.* import tech.beshu.ror.constants -import tech.beshu.ror.es.actions.rrtestconfig.{RRTestConfigActionType, RRTestConfigRequest, RRTestConfigResponse} +import tech.beshu.ror.es.actions.rrtestsettings.{RRTestSettingsActionType, RRTestSettingsRequest, RRTestSettingsResponse} import tech.beshu.ror.es.utils.RestToXContentWithStatusListener import java.util import scala.jdk.CollectionConverters.* -class RestRRTestConfigAction +class RestRRTestSettingsAction extends BaseRestHandler with RestHandler { override def routes(): util.List[Route] = List( - new Route(GET, constants.PROVIDE_TEST_CONFIG_PATH), - new Route(POST, constants.UPDATE_TEST_CONFIG_PATH), - new Route(DELETE, constants.DELETE_TEST_CONFIG_PATH), + new Route(GET, constants.PROVIDE_TEST_SETTINGS_PATH), + new Route(POST, constants.UPDATE_TEST_SETTINGS_PATH), + new Route(DELETE, constants.DELETE_TEST_SETTINGS_PATH), new Route(GET, constants.PROVIDE_LOCAL_USERS_PATH) ).asJava override val getName: String = "ror-test-config-handler" override def prepareRequest(request: RestRequest, client: NodeClient): RestChannelConsumer = new RestChannelConsumer { - private val rorTestConfigRequest = RRTestConfigRequest.createFrom(request) + private val rorTestSettingsRequest = RRTestSettingsRequest.createFrom(request) override def accept(channel: RestChannel): Unit = { - client.execute(new RRTestConfigActionType, rorTestConfigRequest, new RestToXContentWithStatusListener[RRTestConfigResponse](channel)) + client.execute(new RRTestSettingsActionType, rorTestSettingsRequest, new RestToXContentWithStatusListener[RRTestSettingsResponse](channel)) } } } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala b/es92x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala index 494e9150b4..438011eecf 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/dlsfls/RoleIndexSearcherWrapper.scala @@ -54,7 +54,6 @@ object RoleIndexSearcherWrapper extends Logging { } .map(r => (r, r)) case None => - logger.debug(s"FLS: ${constants.FIELDS_TRANSIENT} not found in threadContext") Success((reader, reader)) } } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala b/es92x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala index 2f6a3aac03..9365230fe3 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/handler/AclAwareRequestFilter.scala @@ -75,7 +75,7 @@ import tech.beshu.ror.es.handler.request.context.types.repositories.* import tech.beshu.ror.es.handler.request.context.types.ror.* import tech.beshu.ror.es.handler.request.context.types.snapshots.* import tech.beshu.ror.es.handler.request.context.types.templates.* -import tech.beshu.ror.es.{AtEsLevelUpdateActionResponseListener, HidingInternalErrorDetailsRorActionListener, RorActionListener, RorClusterService, RorRestChannel} +import tech.beshu.ror.es.{HidingInternalErrorDetailsRorActionListener, RorActionListener, RorClusterService, RorRestChannel, AtEsLevelUpdateActionResponseListener} import tech.beshu.ror.implicits.* import tech.beshu.ror.syntax.* diff --git a/es92x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala b/es92x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala index a8727bb24a..9c00906853 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/handler/RorNotAvailableRequestHandler.scala @@ -16,12 +16,12 @@ */ package tech.beshu.ror.es.handler -import tech.beshu.ror.configuration.RorBootConfiguration -import tech.beshu.ror.configuration.RorBootConfiguration.{RorFailedToStartResponse, RorNotStartedResponse} +import tech.beshu.ror.settings.es.RorBootSettings +import tech.beshu.ror.settings.es.RorBootSettings.{RorFailedToStartResponse, RorNotStartedResponse} import tech.beshu.ror.es.handler.AclAwareRequestFilter.EsContext import tech.beshu.ror.es.handler.response.{ForbiddenResponse, ServiceNotAvailableResponse} -final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { +final class RorNotAvailableRequestHandler(settings: RorBootSettings) { def handleRorNotReadyYet(esContext: EsContext): Unit = { val response = prepareNotReadyYetResponse() @@ -34,7 +34,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareNotReadyYetResponse() = { - config.rorNotStartedResponse.httpCode match { + settings.rorNotStartedResponse.httpCode match { case RorNotStartedResponse.HttpCode.`403` => ForbiddenResponse.createRorNotReadyYetResponse() case RorNotStartedResponse.HttpCode.`503` => @@ -43,7 +43,7 @@ final class RorNotAvailableRequestHandler(config: RorBootConfiguration) { } private def prepareFailedToStartResponse() = { - config.rorFailedToStartResponse.httpCode match { + settings.rorFailedToStartResponse.httpCode match { case RorFailedToStartResponse.HttpCode.`403` => ForbiddenResponse.createRorStartingFailureResponse() case RorFailedToStartResponse.HttpCode.`503` => diff --git a/es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala b/es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala similarity index 71% rename from es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala rename to es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index 40ae6d97e0..c1c6c8a26b 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexJsonContentService.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -17,26 +17,27 @@ package tech.beshu.ror.es.services import cats.implicits.* +import io.circe.Json +import io.circe.parser.* import monix.eval.Task import org.apache.logging.log4j.scala.Logging import org.elasticsearch.ResourceNotFoundException import org.elasticsearch.action.support.WriteRequest.RefreshPolicy import org.elasticsearch.client.internal.node.NodeClient +import org.elasticsearch.index.IndexNotFoundException import org.elasticsearch.injection.guice.Inject import org.elasticsearch.xcontent.XContentType import tech.beshu.ror.accesscontrol.domain.IndexName import tech.beshu.ror.boot.RorSchedulers -import tech.beshu.ror.es.IndexJsonContentService -import tech.beshu.ror.es.IndexJsonContentService.* +import tech.beshu.ror.es.IndexDocumentManager +import tech.beshu.ror.es.IndexDocumentManager.* import tech.beshu.ror.implicits.* -import tech.beshu.ror.utils.ScalaOps.* import scala.annotation.unused -import scala.jdk.CollectionConverters.* -class EsIndexJsonContentService(client: NodeClient, - @unused constructorDiscriminator: Unit) - extends IndexJsonContentService +class EsIndexDocumentManager(client: NodeClient, + @unused constructorDiscriminator: Unit) + extends IndexDocumentManager with Logging { @Inject @@ -44,8 +45,7 @@ class EsIndexJsonContentService(client: NodeClient, this(client, ()) } - override def sourceOf(index: IndexName.Full, - id: String): Task[Either[ReadError, Map[String, String]]] = { + override def documentAsJson(index: IndexName.Full, id: String): Task[Either[ReadError, Json]] = { Task { client .get( @@ -59,32 +59,33 @@ class EsIndexJsonContentService(client: NodeClient, } .map { response => if (response.isExists) { - Option(response.getSourceAsMap) match { - case Some(map) => - val source = map.asScala.toMap.asStringMap - logger.debug(s"Document [${index.show} ID=$id] _source: ${showSource(source)}") - Right(source) + Option(response.getSourceAsString) match { + case Some(source) => + logger.debug(s"Document [${index.show} ID=$id] _source: $source") + parse(source) match { + case Right(value) => Right(value) + case Left(failure) => throw new IllegalStateException(s"Cannot parse document source to JSON: ${failure.toString}") + } case None => logger.warn(s"Document [${index.show} ID=$id] _source is not available. Assuming it's empty") - Right(Map.empty[String, String]) + Right(Json.Null) } } else { logger.debug(s"Document [${index.show} ID=$id] not exist") - Left(ContentNotFound) + Left(DocumentNotFound) } } .executeOn(RorSchedulers.blockingScheduler) .onErrorRecover { - case _: ResourceNotFoundException => Left(ContentNotFound) + case _: IndexNotFoundException => Left(IndexNotFound) + case _: ResourceNotFoundException => Left(DocumentNotFound) case ex => logger.error(s"Cannot get source of document [${index.show} ID=$id]", ex) - Left(CannotReachContentSource) + Left(DocumentUnreachable) } } - override def saveContent(index: IndexName.Full, - id: String, - content: Map[String, String]): Task[Either[WriteError, Unit]] = { + override def saveDocumentJson(index: IndexName.Full, id: String, document: Json): Task[Either[WriteError, Unit]] = { Task { client .index( @@ -92,7 +93,7 @@ class EsIndexJsonContentService(client: NodeClient, .prepareIndex() .setIndex(index.name.value) .setId(id) - .setSource(content.asJava, XContentType.JSON) + .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) .request() ) @@ -114,8 +115,4 @@ class EsIndexJsonContentService(client: NodeClient, Left(CannotWriteToIndex) } } - - private def showSource(source: Map[String, String]) = { - ujson.write(source) - } } diff --git a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 95fd8dbc81..b98eed4c2f 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,7 +27,7 @@ import org.elasticsearch.telemetry.TelemetryProvider import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry -import tech.beshu.ror.configuration.SslConfiguration.ExternalSslConfiguration +import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -35,15 +35,14 @@ class SSLNetty4HttpServerTransport(settings: Settings, threadPool: ThreadPool, xContentRegistry: NamedXContentRegistry, dispatcher: HttpServerTransport.Dispatcher, - ssl: ExternalSslConfiguration, + ssl: ExternalSslSettings, clusterSettings: ClusterSettings, sharedGroupFactory: SharedGroupFactory, - telemetryProvider: TelemetryProvider, - fipsCompliant: Boolean) + telemetryProvider: TelemetryProvider) extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, telemetryProvider, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, ssl.clientAuthenticationEnabled) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2fa1d7871c..58d76ddebb 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -29,7 +29,8 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} -import tech.beshu.ror.configuration.SslConfiguration.InternodeSslConfiguration +import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant +import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -42,14 +43,13 @@ class SSLNetty4InternodeServerTransport(settings: Settings, circuitBreakerService: CircuitBreakerService, namedWriteableRegistry: NamedWriteableRegistry, networkService: NetworkService, - ssl: InternodeSslConfiguration, - sharedGroupFactory: SharedGroupFactory, - fipsCompliant: Boolean) + ssl: InternodeSslSettings, + sharedGroupFactory: SharedGroupFactory) extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl, fipsCompliant, ssl.certificateVerificationEnabled) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, fipsCompliant, clientAuthenticationEnabled = false) + private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) + private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { @@ -68,7 +68,7 @@ class SSLNetty4InternodeServerTransport(settings: Settings, channelHandlerContext = ctx, serverName = Option(node.getAttributes.get("server_name")).map(new SNIHostName(_)), enableHostnameVerification = ssl.hostnameVerificationEnabled, - fipsCompliant = fipsCompliant + fipsCompliant = ssl.fipsMode.isSslFipsCompliant ) ctx.pipeline().replace(this, "internode_ssl_client", new SslHandler(sslEngine)) super.connect(ctx, remoteAddress, localAddress, promise) diff --git a/es92x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala b/es92x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala index 6b7344e3ae..ff7bac1b75 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/utils/EsEnvProvider.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.es.utils +import better.files.File import org.elasticsearch.Version import org.elasticsearch.cluster.ClusterName import org.elasticsearch.env.Environment @@ -26,8 +27,8 @@ object EsEnvProvider { def create(environment: Environment): EsEnv = { val settings = environment.settings() EsEnv( - configPath = environment.configDir(), - modulesPath = environment.modulesDir(), + configDir = File(environment.configDir()), + modulesDir = File(environment.modulesDir()), esVersion = EsVersion(major = Version.CURRENT.major, minor = Version.CURRENT.minor, revision = Version.CURRENT.revision), esNodeSettings = EsNodeSettings( nodeName = Node.NODE_NAME_SETTING.get(settings), From 5e47b86dcfb6a45e84df08df2ebcc0a43febaf6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 28 Nov 2025 09:43:59 +0100 Subject: [PATCH 052/103] fixing problem with resolving indices in ROR for ES 9.1.7 --- es91x/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es91x/gradle.properties b/es91x/gradle.properties index 100db48134..32b97f72bb 100644 --- a/es91x/gradle.properties +++ b/es91x/gradle.properties @@ -1 +1 @@ -latestSupportedEsVersion=9.1.6 +latestSupportedEsVersion=9.1.7 From ef0d226ce1e8a30deb896f3acedb440246a9abf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 28 Nov 2025 09:44:55 +0100 Subject: [PATCH 053/103] bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 10c48536bd..b16d87da2f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ publishedPluginVersion=1.67.2 -pluginVersion=1.67.2 +pluginVersion=1.67.3 pluginName=readonlyrest org.gradle.jvmargs=-Xmx6144m From 691fe2f3159c7e6d7414031410db8a0006fe8111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 28 Nov 2025 10:17:44 +0100 Subject: [PATCH 054/103] wip --- .../ror/unit/utils/MatcherWithWildcardsScalaTest.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/test/scala/tech/beshu/ror/unit/utils/MatcherWithWildcardsScalaTest.scala b/core/src/test/scala/tech/beshu/ror/unit/utils/MatcherWithWildcardsScalaTest.scala index 4ba8352121..f3e6e707e8 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/utils/MatcherWithWildcardsScalaTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/utils/MatcherWithWildcardsScalaTest.scala @@ -123,14 +123,18 @@ class MatcherWithWildcardsScalaTest "filter result" should { "reject not related haystack" in { forAll("matchers", "haystack") { (matchers: List[String], haystack: Set[String]) => - val matcher = PatternsMatcher.create(matchers)(caseSensitiveStringMatchable) + // Filter out wildcard characters to ensure literal string matching + val literalMatchers = matchers.filter(m => !m.contains('*') && !m.contains('?')) + val matcher = PatternsMatcher.create(literalMatchers)(caseSensitiveStringMatchable) val result = matcher.filter(haystack) - result shouldBe haystack.intersect(matchers.toCovariantSet) + result shouldBe haystack.intersect(literalMatchers.toCovariantSet) } } "contain all haystack if haystack is in matchers" in { forAll("matchers", "haystack") { (matchers: List[String], haystack: Set[String]) => - val matcher = PatternsMatcher.create(matchers ++ haystack)(caseSensitiveStringMatchable) + // Filter out wildcard characters to ensure literal string matching + val literalMatchers = matchers.filter(m => !m.contains('*') && !m.contains('?')) + val matcher = PatternsMatcher.create(literalMatchers ++ haystack)(caseSensitiveStringMatchable) val result = matcher.filter(haystack) result shouldBe haystack } From 763ffc60dde948b8043937f5935a782ddad3ce1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 11:46:11 +0100 Subject: [PATCH 055/103] bump pre version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c00b8d789d..83a2dd8924 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ publishedPluginVersion=1.67.3 -pluginVersion=1.68.0-pre9 +pluginVersion=1.68.0-pre10 pluginName=readonlyrest org.gradle.jvmargs=-Xmx6144m From aa57a06d07864c5e45e396aebc3e08a94710fe43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 12:06:30 +0100 Subject: [PATCH 056/103] wip --- core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala | 2 +- .../beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala | 2 +- .../tech/beshu/ror/settings/{es => }/RorProperties.scala | 2 +- .../ror/settings/es/LoadingRorCoreStrategySettings.scala | 5 +++-- .../beshu/ror/settings/es/RorSettingsSourcesConfig.scala | 1 + 5 files changed, 7 insertions(+), 5 deletions(-) rename core/src/main/scala/tech/beshu/ror/settings/{es => }/RorProperties.scala (99%) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 0755d7f5e7..88a3102e16 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -190,7 +190,7 @@ object RorInstance { private def modeFrom(strategy: LoadingRorCoreStrategySettings) = { strategy match { - case LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings => + case LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings => Mode.NoPeriodicIndexCheck case LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => Mode.NoPeriodicIndexCheck diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index 7c1cb23a30..9b81134346 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -39,7 +39,7 @@ object SettingsRelatedCreatorsAndLoaders { val mainSettingsFileSource = MainSettingsFileSource.create(settingsFile, settingsYamlParser) val testSettingsIndexSource = TestSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { - case s@LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings => + case s@LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) case s@LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(retryStrategySettings, _) => new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader( diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala similarity index 99% rename from core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala rename to core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala index f07d3f3276..f4d057d2a4 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ */ -package tech.beshu.ror.settings.es +package tech.beshu.ror.settings import better.files.File import cats.Show diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala index 59f6f4a038..c3c09c5c62 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala @@ -24,6 +24,7 @@ import monix.eval.Task import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider +import tech.beshu.ror.settings.RorProperties import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} @@ -35,7 +36,7 @@ import scala.language.{implicitConversions, postfixOps} sealed trait LoadingRorCoreStrategySettings object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport { - case object ForceLoadingFromFile$Settings extends LoadingRorCoreStrategySettings + case object ForceLoadingFromFileSettings extends LoadingRorCoreStrategySettings final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, coreRefreshSettings: CoreRefreshSettings) extends LoadingRorCoreStrategySettings @@ -85,7 +86,7 @@ object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport default = false ) flatMap { case true => - Decoder.const(LoadingRorCoreStrategySettings.ForceLoadingFromFile$Settings) + Decoder.const(LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings) case false => for { loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala index fe3296cf9c..dfa602ad82 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSettingsSourcesConfig.scala @@ -25,6 +25,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.accesscontrol.domain.{IndexName, RorSettingsFile, RorSettingsIndex} import tech.beshu.ror.accesscontrol.factory.decoders.common.* import tech.beshu.ror.es.EsEnv +import tech.beshu.ror.settings.RorProperties import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.yaml.YamlKeyDecoder From 8c1e017f83bb670e872997790db5133ef4805a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 14:06:48 +0100 Subject: [PATCH 057/103] test fix --- .../ror/tools/PatchingOfAptBasedEsInstallationSuite.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala index 6edaa0682d..3417270914 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala @@ -99,7 +99,7 @@ class PatchingOfAptBasedEsInstallationSuite extends AnyWordSpec with ESVersionSu } dockerLogs should include("ReadonlyREST is waiting for full Elasticsearch init") dockerLogs should include("Elasticsearch fully initiated. ReadonlyREST can continue ...") - dockerLogs should include("Loading Elasticsearch settings from file:") + dockerLogs should include("Loading ReadonlyREST main settings from file") dockerLogs shouldNot include("Cannot verify if the ES was patched") dockerLogs should include("ReadonlyREST was loaded") } @@ -112,7 +112,7 @@ class PatchingOfAptBasedEsInstallationSuite extends AnyWordSpec with ESVersionSu } dockerLogs should include("ReadonlyREST is waiting for full Elasticsearch init") dockerLogs should include("Elasticsearch fully initiated. ReadonlyREST can continue ...") - dockerLogs should include("Loading Elasticsearch settings from file:") + dockerLogs should include("Loading ReadonlyREST main settings from file") dockerLogs shouldNot include("Cannot verify if the ES was patched") dockerLogs should include("ReadonlyREST was loaded") } @@ -122,7 +122,7 @@ class PatchingOfAptBasedEsInstallationSuite extends AnyWordSpec with ESVersionSu } dockerLogs should include("ReadonlyREST is waiting for full Elasticsearch init") dockerLogs should include("Elasticsearch fully initiated. ReadonlyREST can continue ...") - dockerLogs should include("Loading Elasticsearch settings from file:") + dockerLogs should include("Loading ReadonlyREST main settings from file") dockerLogs should include("Cannot verify if the ES was patched. component [readonlyrest], module [ALL-UNNAMED], class [class tech.beshu.ror.tools.core.utils.EsDirectory$], entitlement [file], operation [read], path [/usr/share/elasticsearch]") dockerLogs should include("ReadonlyREST was loaded") } From ea07b67b1ad969f97e5a19cf3476f8ead4b79034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 14:49:38 +0100 Subject: [PATCH 058/103] test fix --- .../suites/audit/RemoteClusterAuditingToolsSuite.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala index 155a553e04..92e5989c9b 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala @@ -107,7 +107,7 @@ class RemoteClusterAuditingToolsSuite // This test suite does not execute on Windows: there is currently no Windows version of ToxiproxyContainer ignoreOnWindows { "Should report audit events in round-robin mode, even when some nodes are unreachable" in { - rorApiManager.updateRorInIndexConfig(baseRorConfig).forceOKStatusOrConfigAlreadyLoaded() + rorApiManager.updateRorInIndexSettings(baseRorConfig).forceOKStatusOrSettingsAlreadyLoaded() val auditNode1 = proxiedContainers(0) val auditNode2 = proxiedContainers(1) From 6954bacdb395f98a3ef95cfa260a224d6cbce754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 15:03:28 +0100 Subject: [PATCH 059/103] test fix --- .../ror/integration/suites/base/BaseAdminApiSuite.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala index 4c4efd92f9..72e1c53902 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala @@ -75,7 +75,7 @@ trait BaseAdminApiSuite rorWithNoIndexConfigAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, - Settings = getResourceContent("/admin_api/readonlyrest_index.yml") + settings = getResourceContent("/admin_api/readonlyrest_index.yml") ) .force() @@ -96,7 +96,7 @@ trait BaseAdminApiSuite rorWithNoIndexConfigAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, - Settings = getResourceContent("/admin_api/readonlyrest.yml") + settings = getResourceContent("/admin_api/readonlyrest.yml") ) .force() @@ -131,7 +131,7 @@ trait BaseAdminApiSuite rorWithNoIndexConfigAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, - Settings = getResourceContent("/admin_api/readonlyrest_with_ldap.yml") + settings = getResourceContent("/admin_api/readonlyrest_with_ldap.yml") ) .force() @@ -1258,7 +1258,6 @@ trait BaseAdminApiSuite )) } - private def operationNotAllowed(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 403 From cb0d4ebb923418f031ca41173e05f636f09d37ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 4 Dec 2025 23:17:05 +0100 Subject: [PATCH 060/103] test fix --- core/src/main/scala/tech/beshu/ror/implicits.scala | 4 ++-- .../beshu/ror/integration/suites/base/BaseAdminApiSuite.scala | 4 ++-- .../ror/tools/PatchingOfAptBasedEsInstallationSuite.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 448abadcbd..624764e3b4 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -443,8 +443,8 @@ trait LogsShowInstances } implicit val indexSettingsSourceLoadingErrorShow: Show[IndexSettingsSource.LoadingError] = Show.show { - case IndexSettingsSource.LoadingError.IndexNotFound => "cannot find ReadonlyREST settings index" - case IndexSettingsSource.LoadingError.DocumentNotFound => "cannot found document with ReadonlyREST settings" + case IndexSettingsSource.LoadingError.IndexNotFound => "Cannot find ReadonlyREST settings index" + case IndexSettingsSource.LoadingError.DocumentNotFound => "Cannot found document with ReadonlyREST settings" } implicit val indexSettingsSourceSavingErrorShow: Show[IndexSettingsSource.SavingError] = Show.show { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala index 72e1c53902..32ba76a027 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala @@ -120,7 +120,7 @@ trait BaseAdminApiSuite s""" |{ | "status": "ko", - | "message": "Cannot find settings index" + | "message": "Cannot find ReadonlyREST settings index" |} |""".stripMargin )) @@ -1101,7 +1101,7 @@ trait BaseAdminApiSuite """ |{ | "status": "empty", - | "message": "Cannot find settings index" + | "message": "Cannot find ReadonlyREST settings index" |} |""".stripMargin )) diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala index 3417270914..24971788b6 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala @@ -69,7 +69,7 @@ class PatchingOfAptBasedEsInstallationSuite extends AnyWordSpec with ESVersionSu } dockerLogs should include("ReadonlyREST is waiting for full Elasticsearch init") dockerLogs should include("Elasticsearch fully initiated. ReadonlyREST can continue ...") - dockerLogs should include("Loading Elasticsearch settings from file:") + dockerLogs should include("Loading ReadonlyREST main settings from file") dockerLogs should include("Cannot verify if the ES was patched") dockerLogs should include("ReadonlyREST was loaded") } @@ -84,7 +84,7 @@ class PatchingOfAptBasedEsInstallationSuite extends AnyWordSpec with ESVersionSu } dockerLogs should include("ReadonlyREST is waiting for full Elasticsearch init") dockerLogs should include("Elasticsearch fully initiated. ReadonlyREST can continue ...") - dockerLogs should include("Loading Elasticsearch settings from file:") + dockerLogs should include("Loading ReadonlyREST main settings from file") dockerLogs shouldNot include("Cannot verify if the ES was patched") dockerLogs should include("ReadonlyREST was loaded") } From a41a7d823264052179f623087db219c7ca337fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 5 Dec 2025 11:53:12 +0100 Subject: [PATCH 061/103] wip --- .../integration/suites/RorStartingSuite.scala | 83 +++++-------------- .../utils/ExampleEsWithRorContainer.scala | 1 - .../src/main/resources/basic/readonlyrest.yml | 2 +- .../ElasticsearchNodeWaitingStrategy.scala | 57 +++++++++---- .../utils/containers/EsContainerCreator.scala | 28 +++++-- .../EsContainerWithNoSecurity.scala | 4 +- .../EsContainerWithRorAndXpackSecurity.scala | 15 ++-- .../EsContainerWithRorSecurity.scala | 4 +- .../EsContainerWithXpackSecurity.scala | 4 +- 9 files changed, 101 insertions(+), 97 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala index 3a9bc161f5..1782a16d41 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala @@ -22,8 +22,9 @@ import monix.execution.Scheduler import monix.execution.atomic.AtomicInt import org.scalatest.wordspec.AnyWordSpec import tech.beshu.ror.integration.utils.ESVersionSupportForAnyWordSpecLike -import tech.beshu.ror.utils.containers.EsContainerCreator.EsNodeSettings import tech.beshu.ror.utils.containers.* +import tech.beshu.ror.utils.containers.ElasticsearchNodeWaitingStrategy.AwaitingReadyStrategy.WaitForEsRestApiResponsive +import tech.beshu.ror.utils.containers.EsContainerCreator.EsNodeSettings import tech.beshu.ror.utils.containers.images.ReadonlyRestWithEnabledXpackSecurityPlugin import tech.beshu.ror.utils.elasticsearch.BaseManager.JSON import tech.beshu.ror.utils.elasticsearch.SearchManager @@ -32,7 +33,7 @@ import tech.beshu.ror.utils.misc.EsModulePatterns import scala.concurrent.duration.* import scala.language.postfixOps -import scala.util.{Failure, Success, Try} +import scala.util.Try class RorStartingSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLike { @@ -68,13 +69,9 @@ class RorStartingSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLi rorConfigFile = validRorConfigFile, additionalEsYamlEntries = additionalEsYamlEntries ) + esContainer.start().runSyncUnsafe(5 minutes) try { - Task - .parSequence(List( - testCode(esContainer), - esContainer.start(), - )) - .runSyncUnsafe(5 minutes) + testCode(esContainer) } finally { esContainer.stop().runSyncUnsafe() } @@ -83,65 +80,30 @@ class RorStartingSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLi private def testRorStartup(usingManager: TestEsContainerManager, expectedResponseCode: Int): Task[Unit] = { for { restClient <- usingManager.createRestClient - searchTestResults <- searchTest(client = restClient, searchAttemptsCount = 200) - result <- handleResults(searchTestResults, expectedResponseCode) + searchTestResult <- searchTest(client = restClient) + result <- handleResult(searchTestResult, expectedResponseCode) } yield result } - private def searchTest(client: RestClient, searchAttemptsCount: Int): Task[Seq[TestResponse]] = { - searchAndWait(new SearchManager(client, esVersionUsed), searchAttemptsCount).map(_.distinct) + private def searchTest(client: RestClient): Task[TestResponse] = Task.delay { + val searchManager = new SearchManager(client, esVersionUsed) + val response = searchManager.searchAll("*") + TestResponse(response.responseCode, response.responseJson) } - private def searchAndWait(manager: SearchManager, attemptLeft: Int): Task[List[TestResponse]] = { - if (attemptLeft == 0) - Task.now(List.empty) - else { - for { - currentResponses <- search(manager) - responses <- currentResponses match { - case Right(responses) => for { - _ <- Task.sleep(1 second) - otherResponses <- searchAndWait(manager, attemptLeft - 1) - } yield responses ::: otherResponses - case Left(responses) => - Task.now(responses) - } - } yield responses - } - } - - private def search(manger: SearchManager): Task[Either[List[TestResponse], List[TestResponse]]] = Task.delay { - Try(manger.searchAll("*")) match { - case Success(response) if response.isSuccess => - Left(List(TestResponse(response.responseCode, response.responseJson))) - case Success(response) => - Right(List(TestResponse(response.responseCode, response.responseJson))) - case Failure(_) => - Right(List.empty) - } - } - - private def handleResults(results: Seq[TestResponse], expectedResponseCode: Int): Task[Unit] = { - val hasEsRespondedWithNotStartedResponse = results - .filter { response => - response.responseCode == expectedResponseCode - } - .exists { response => - response - .responseJson("error") - .obj("root_cause") - .arr.exists { json => - json("reason").str == "Forbidden by ReadonlyREST" && - json("due_to").str == "READONLYREST_NOT_READY_YET" - } + private def handleResult(result: TestResponse, expectedResponseCode: Int): Task[Unit] = { + val isResponseCodeOk = result.responseCode == expectedResponseCode + val isResponseErrorOk = result + .responseJson("error") + .obj("root_cause") + .arr.exists { json => + json("reason").str == "Forbidden by ReadonlyREST" && + json("due_to").str == "READONLYREST_NOT_READY_YET" } - - val hasEsRespondedWithSuccess = results.exists(_.responseCode == 200) - - if (hasEsRespondedWithNotStartedResponse && hasEsRespondedWithSuccess) { + if (isResponseCodeOk && isResponseErrorOk) { Task.unit } else { - Task.raiseError(new IllegalStateException(s"Test failed. Expected success response and ROR failed to start response but was: [$results]")) + Task.raiseError(new IllegalStateException(s"Test failed. Expected success response and ROR failed to start response but was: [$result]")) } } } @@ -192,7 +154,8 @@ private object RorStartingSuite extends EsModulePatterns { ), allNodeNames = NonEmptyList.of(nodeName), nodeDataInitializer = NoOpElasticsearchNodeDataInitializer, - startedClusterDependencies = StartedClusterDependencies(List.empty) + startedClusterDependencies = StartedClusterDependencies(List.empty), + awaitingReadyStrategy = WaitForEsRestApiResponsive ) } } diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala index b9f1284387..75513c2243 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala @@ -26,7 +26,6 @@ import tech.beshu.ror.utils.containers.* import tech.beshu.ror.utils.containers.ElasticsearchNodeWaitingStrategy.AwaitingReadyStrategy import tech.beshu.ror.utils.containers.EsContainerCreator.EsNodeSettings import tech.beshu.ror.utils.containers.exceptions.ContainerCreationException -import tech.beshu.ror.utils.containers.images.Elasticsearch.EsInstallationType import tech.beshu.ror.utils.containers.images.domain.Enabled import tech.beshu.ror.utils.containers.images.{Elasticsearch, ReadonlyRestWithEnabledXpackSecurityPlugin} import tech.beshu.ror.utils.containers.windows.{WindowsEsDirectoryManager, WindowsEsSetup} diff --git a/tests-utils/src/main/resources/basic/readonlyrest.yml b/tests-utils/src/main/resources/basic/readonlyrest.yml index ac2f02dab2..05f13e0af5 100644 --- a/tests-utils/src/main/resources/basic/readonlyrest.yml +++ b/tests-utils/src/main/resources/basic/readonlyrest.yml @@ -4,4 +4,4 @@ readonlyrest: - name: "CONTAINER ADMIN - basic" verbosity: "error" type: "allow" - auth_key: "admin:container" \ No newline at end of file + auth_key1: "admin:container" \ No newline at end of file diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala index ebb2da04f5..0710dc1898 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.utils.containers import com.typesafe.scalalogging.StrictLogging import monix.eval.Coeval import org.testcontainers.containers.ContainerLaunchException -import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy +import org.testcontainers.containers.wait.strategy.{AbstractWaitStrategy, HttpWaitStrategy} import tech.beshu.ror.utils.containers.ElasticsearchNodeWaitingStrategy.AwaitingReadyStrategy import tech.beshu.ror.utils.httpclient.RestClient import tech.beshu.ror.utils.misc.{EsStartupChecker, Version} @@ -29,41 +29,66 @@ import scala.util.Try class ElasticsearchNodeWaitingStrategy(esVersion: String, containerName: String, restClient: Coeval[RestClient], - initializer: ElasticsearchNodeDataInitializer = NoOpElasticsearchNodeDataInitializer, + initializer: ElasticsearchNodeDataInitializer, strategy: AwaitingReadyStrategy) extends AbstractWaitStrategy with StrictLogging { override def waitUntilReady(): Unit = { - val client = restClient.runAttempt().fold(throw _, identity) - val checker = - if (Version.greaterOrEqualThan(esVersion, 8, 3, 0)) { - EsStartupChecker.greenEsClusterChecker(containerName, client) - } else { - EsStartupChecker.accessibleEsChecker(containerName, client) - } - val started = strategy match { + val client = createRestClient() + if (!waitForStart(client)) { + throw new ContainerLaunchException(s"Cannot start ROR-ES container [$containerName]") + } + initialize(client) + } + + private def waitForStart(client: RestClient) = { + strategy match { case AwaitingReadyStrategy.WaitForEsReadiness => - checker.waitForStart() + createChecker(client).waitForStart() case AwaitingReadyStrategy.ImmediatelyTreatAsReady => true + case AwaitingReadyStrategy.WaitForEsRestApiResponsive => + waitForRestEsApi() } - if (!started) { - throw new ContainerLaunchException(s"Cannot start ROR-ES container [$containerName]") - } + } + + private def initialize(client: RestClient): Unit = { Try(initializer.initialize(esVersion, client)) .fold( ex => throw new ContainerLaunchException(s"Cannot start ROR-ES container [$containerName]", ex), identity ) } + + private def createRestClient() = { + restClient.runAttempt().fold(throw _, identity) + } + + private def createChecker(client: RestClient) = { + if (Version.greaterOrEqualThan(esVersion, 8, 3, 0)) { + EsStartupChecker.greenEsClusterChecker(containerName, client) + } else { + EsStartupChecker.accessibleEsChecker(containerName, client) + } + } + + private def waitForRestEsApi() = { + val esRestApiWaitStrategy = new HttpWaitStrategy() + .usingTls().allowInsecure() + .forPort(9200) + .forPath("/") + .forStatusCodeMatching(_ => true) + Try(esRestApiWaitStrategy.waitUntilReady(waitStrategyTarget)).isSuccess + } } object ElasticsearchNodeWaitingStrategy { sealed trait AwaitingReadyStrategy object AwaitingReadyStrategy { - case object WaitForEsReadiness extends AwaitingReadyStrategy - case object ImmediatelyTreatAsReady extends AwaitingReadyStrategy + case object WaitForEsReadiness extends AwaitingReadyStrategy + case object ImmediatelyTreatAsReady extends AwaitingReadyStrategy + case object WaitForEsRestApiResponsive extends AwaitingReadyStrategy } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala index 36dc08cbc4..a3c2b8e5da 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala @@ -21,6 +21,7 @@ import cats.data.NonEmptyList import com.dimafeng.testcontainers.SingleContainer import org.testcontainers.containers.GenericContainer as JavaGenericContainer import org.testcontainers.containers.output.OutputFrame +import tech.beshu.ror.utils.containers.ElasticsearchNodeWaitingStrategy.AwaitingReadyStrategy import tech.beshu.ror.utils.containers.EsContainerCreator.EsNodeSettings import tech.beshu.ror.utils.containers.exceptions.ContainerCreationException import tech.beshu.ror.utils.containers.images.Elasticsearch.EsInstallationType @@ -53,20 +54,21 @@ trait EsContainerCreator { nodeDataInitializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, esInstallationType: EsInstallationType = defaultEsInstallationType, - additionalLogConsumer: Option[Consumer[OutputFrame]] = None): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]] = None, + awaitingReadyStrategy: AwaitingReadyStrategy = AwaitingReadyStrategy.WaitForEsReadiness): EsContainer = { val project = nodeSettings.esVersion match { case EsVersion.DeclaredInProject => RorPluginGradleProject.fromSystemProperty case EsVersion.SpecificVersion(version) => RorPluginGradleProject.customModule(version) } nodeSettings.securityType match { case SecurityType.RorWithXpackSecurity(attributes) => - createEsWithRorAndXpackSecurityContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer) + createEsWithRorAndXpackSecurityContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer, awaitingReadyStrategy) case SecurityType.RorSecurity(attributes) => - createEsWithRorContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer) + createEsWithRorContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer, awaitingReadyStrategy) case SecurityType.XPackSecurity(attributes) => - createEsWithXpackContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer) + createEsWithXpackContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, attributes, startedClusterDependencies, esInstallationType, additionalLogConsumer, awaitingReadyStrategy) case SecurityType.NoSecurityCluster => - createEsWithNoSecurityContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, startedClusterDependencies, esInstallationType, additionalLogConsumer) + createEsWithNoSecurityContainer(nodeSettings, allNodeNames, project, nodeDataInitializer, startedClusterDependencies, esInstallationType, additionalLogConsumer, awaitingReadyStrategy) } } @@ -77,7 +79,8 @@ trait EsContainerCreator { attributes: ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes, startedClusterDependencies: StartedClusterDependencies, esInstallationType: EsInstallationType, - additionalLogConsumer: Option[Consumer[OutputFrame]]) = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy) = { val rorPluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin file assembly failed")) val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorConfigFileName) @@ -104,6 +107,7 @@ trait EsContainerCreator { initializer = nodeDataInitializer, startedClusterDependencies = startedClusterDependencies, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy ) } @@ -114,7 +118,8 @@ trait EsContainerCreator { attributes: ReadonlyRestPlugin.Config.Attributes, startedClusterDependencies: StartedClusterDependencies, esInstallationType: EsInstallationType, - additionalLogConsumer: Option[Consumer[OutputFrame]]) = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy) = { val rorPluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin file assembly failed")) val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorConfigFileName) @@ -141,6 +146,7 @@ trait EsContainerCreator { initializer = nodeDataInitializer, startedClusterDependencies = startedClusterDependencies, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy ) } @@ -151,7 +157,8 @@ trait EsContainerCreator { attributes: XpackSecurityPlugin.Config.Attributes, startedClusterDependencies: StartedClusterDependencies, esInstallationType: EsInstallationType, - additionalLogConsumer: Option[Consumer[OutputFrame]]) = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy) = { EsContainerWithXpackSecurity.create( esVersion = project.getModuleESVersion, esConfig = Elasticsearch.Config( @@ -166,6 +173,7 @@ trait EsContainerCreator { initializer = nodeDataInitializer, startedClusterDependencies = startedClusterDependencies, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy ) } @@ -175,7 +183,8 @@ trait EsContainerCreator { nodeDataInitializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, esInstallationType: EsInstallationType, - additionalLogConsumer: Option[Consumer[OutputFrame]]) = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy) = { EsContainerWithNoSecurity.create( esVersion = project.getModuleESVersion, esConfig = Elasticsearch.Config( @@ -189,6 +198,7 @@ trait EsContainerCreator { initializer = nodeDataInitializer, startedClusterDependencies = startedClusterDependencies, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy ) } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithNoSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithNoSecurity.scala index d6a3f19ea4..f5be296023 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithNoSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithNoSecurity.scala @@ -46,7 +46,8 @@ object EsContainerWithNoSecurity extends StrictLogging { esConfig: Elasticsearch.Config, initializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { new EsContainerWithNoSecurity( esConfig, esVersion, @@ -54,6 +55,7 @@ object EsContainerWithNoSecurity extends StrictLogging { esImageFromDockerfile(esVersion, esConfig), initializer, additionalLogConsumer, + awaitingReadyStrategy ) } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorAndXpackSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorAndXpackSecurity.scala index 62dc2ec442..e5e6471f65 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorAndXpackSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorAndXpackSecurity.scala @@ -51,7 +51,8 @@ object EsContainerWithRorAndXpackSecurity extends StrictLogging { securityConfig: ReadonlyRestWithEnabledXpackSecurityPlugin.Config, initializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { create( esVersion = esVersion, esConfig = esConfig, @@ -60,8 +61,8 @@ object EsContainerWithRorAndXpackSecurity extends StrictLogging { startedClusterDependencies = startedClusterDependencies, customEntrypoint = None, performPatching = true, - awaitingReadyStrategy = AwaitingReadyStrategy.WaitForEsReadiness, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy, ) } @@ -71,8 +72,8 @@ object EsContainerWithRorAndXpackSecurity extends StrictLogging { initializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, customEntrypoint: Option[Path], - awaitingReadyStrategy: AwaitingReadyStrategy, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { create( esVersion = esVersion, esConfig = esConfig, @@ -81,8 +82,8 @@ object EsContainerWithRorAndXpackSecurity extends StrictLogging { startedClusterDependencies = startedClusterDependencies, customEntrypoint = customEntrypoint, performPatching = false, - awaitingReadyStrategy = awaitingReadyStrategy, additionalLogConsumer = additionalLogConsumer, + awaitingReadyStrategy = awaitingReadyStrategy, ) } @@ -93,8 +94,8 @@ object EsContainerWithRorAndXpackSecurity extends StrictLogging { startedClusterDependencies: StartedClusterDependencies, customEntrypoint: Option[Path], performPatching: Boolean, - awaitingReadyStrategy: AwaitingReadyStrategy, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { new EsContainerWithRorAndXpackSecurity( esConfig, esVersion, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorSecurity.scala index 93e56c59a4..3196f0cb3b 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithRorSecurity.scala @@ -52,7 +52,8 @@ object EsContainerWithRorSecurity extends StrictLogging { rorConfig: ReadonlyRestPlugin.Config, initializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { new EsContainerWithRorSecurity( esVersion, esConfig, @@ -64,6 +65,7 @@ object EsContainerWithRorSecurity extends StrictLogging { }, initializer, additionalLogConsumer, + awaitingReadyStrategy ) } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithXpackSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithXpackSecurity.scala index f4bcb99aa1..6d94138f93 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithXpackSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerWithXpackSecurity.scala @@ -49,7 +49,8 @@ object EsContainerWithXpackSecurity extends StrictLogging { xpackSecurityConfig: XpackSecurityPlugin.Config, initializer: ElasticsearchNodeDataInitializer, startedClusterDependencies: StartedClusterDependencies, - additionalLogConsumer: Option[Consumer[OutputFrame]]): EsContainer = { + additionalLogConsumer: Option[Consumer[OutputFrame]], + awaitingReadyStrategy: AwaitingReadyStrategy): EsContainer = { new EsContainerWithXpackSecurity( esVersion, esConfig, @@ -58,6 +59,7 @@ object EsContainerWithXpackSecurity extends StrictLogging { xpackSecurityConfig.attributes.restSslEnabled, initializer, additionalLogConsumer, + awaitingReadyStrategy ) } From ecfcf39a61c19ee2982f33682d6a21a64b5a2c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 5 Dec 2025 14:19:50 +0100 Subject: [PATCH 062/103] fix --- .../ror_starting_response_code/malformed_readonlyrest.yml | 5 +++++ ...tingSuite.scala => RorStartingResponseCodeSuite.scala} | 8 ++++---- tests-utils/src/main/resources/basic/readonlyrest.yml | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 integration-tests/src/test/resources/ror_starting_response_code/malformed_readonlyrest.yml rename integration-tests/src/test/scala/tech/beshu/ror/integration/suites/{RorStartingSuite.scala => RorStartingResponseCodeSuite.scala} (95%) diff --git a/integration-tests/src/test/resources/ror_starting_response_code/malformed_readonlyrest.yml b/integration-tests/src/test/resources/ror_starting_response_code/malformed_readonlyrest.yml new file mode 100644 index 0000000000..ed7ad9a79b --- /dev/null +++ b/integration-tests/src/test/resources/ror_starting_response_code/malformed_readonlyrest.yml @@ -0,0 +1,5 @@ +readonlyrest: + + access_control_rules: + - name: "CONTAINER ADMIN - basic" + auth_key1: "admin:container" \ No newline at end of file diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala similarity index 95% rename from integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala rename to integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index 1782a16d41..3855dea9b8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -35,13 +35,13 @@ import scala.concurrent.duration.* import scala.language.postfixOps import scala.util.Try -class RorStartingSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLike { +class RorStartingResponseCodeSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLike { - import RorStartingSuite.* + import RorStartingResponseCodeSuite.* implicit val scheduler: Scheduler = Scheduler.computation(10) - private val validRorConfigFile = "/basic/readonlyrest.yml" + private val validRorConfigFile = "/ror_starting_response_code/readonlyrest.yml" private val notStartedResponseCodeKey = "readonlyrest.not_started_response_code" @@ -108,7 +108,7 @@ class RorStartingSuite extends AnyWordSpec with ESVersionSupportForAnyWordSpecLi } } -private object RorStartingSuite extends EsModulePatterns { +private object RorStartingResponseCodeSuite extends EsModulePatterns { final case class TestResponse(responseCode: Int, responseJson: JSON) private val uniqueClusterId: AtomicInt = AtomicInt(1) diff --git a/tests-utils/src/main/resources/basic/readonlyrest.yml b/tests-utils/src/main/resources/basic/readonlyrest.yml index 05f13e0af5..ac2f02dab2 100644 --- a/tests-utils/src/main/resources/basic/readonlyrest.yml +++ b/tests-utils/src/main/resources/basic/readonlyrest.yml @@ -4,4 +4,4 @@ readonlyrest: - name: "CONTAINER ADMIN - basic" verbosity: "error" type: "allow" - auth_key1: "admin:container" \ No newline at end of file + auth_key: "admin:container" \ No newline at end of file From f9c11192d387937db37abe09a1042742c0087ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Fri, 5 Dec 2025 22:52:52 +0100 Subject: [PATCH 063/103] fix --- .../ror/integration/suites/AdminApiAuthMockSuite.scala | 2 +- .../suites/AdminApiWithDefaultRorIndexSuite.scala | 4 ++-- .../tech/beshu/ror/integration/suites/ClusterApiSuite.scala | 2 +- .../ror/integration/suites/CrossClusterCallsSuite.scala | 4 ++-- .../ror/integration/suites/DynamicVariablesSuite.scala | 2 +- .../suites/IndexLifecycleManagementApiSuite.scala | 2 +- .../beshu/ror/integration/suites/RemoteReindexSuite.scala | 2 +- .../beshu/ror/integration/suites/RorDisabledSuite.scala | 2 +- .../integration/suites/RorStartingResponseCodeSuite.scala | 4 ++-- .../XpackApiWithRorWithEnabledXpackSecuritySuite.scala | 2 +- .../ror/tools/PatchingOfAptBasedEsInstallationSuite.scala | 2 +- .../beshu/ror/tools/utils/ExampleEsWithRorContainer.scala | 4 ++-- .../beshu/ror/utils/containers/EsContainerCreator.scala | 2 +- .../images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala | 6 +++--- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index b4438bd102..af11b358a4 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -71,7 +71,7 @@ class AdminApiAuthMockSuite RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( rorConfigReloading = Enabled.Yes(2 seconds), rorCustomSettingsIndex = Some(readonlyrestIndexName), - rorConfigFileName = rorConfigFileName + rorSettingsFileName = rorConfigFileName )) ), ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala index c16acb7cfa..276caea870 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala @@ -43,7 +43,7 @@ class AdminApiWithDefaultRorIndexSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorConfigFileName, rorConfigReloading = Enabled.Yes(settingsReloadInterval) )) ) @@ -60,7 +60,7 @@ class AdminApiWithDefaultRorIndexSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName + rorSettingsFileName = rorConfigFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala index 30dc5bafd6..30d6d9f33f 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala @@ -50,7 +50,7 @@ class ClusterApiSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName + rorSettingsFileName = rorConfigFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala index ad33d0220d..0ae6b67c33 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala @@ -54,7 +54,7 @@ class CrossClusterCallsSuite esClusterSettings = EsClusterSettings.create( clusterName = "ROR_L1", securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorConfigFileName, internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )), nodeDataInitializer = localClusterNodeDataInitializer(), @@ -80,7 +80,7 @@ class CrossClusterCallsSuite EsClusterSettings.create( clusterName = name, securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorConfigFileName, internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )), nodeDataInitializer = nodeDataInitializer diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala index 1f7dfdfd2f..c21215c0fe 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala @@ -54,7 +54,7 @@ class DynamicVariablesSuite createLocalClusterContainer( esClusterSettingsCreator( SecurityType.RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName + rorSettingsFileName = rorConfigFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala index 97e46eb450..2a1cdb32b1 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala @@ -62,7 +62,7 @@ class IndexLifecycleManagementApiSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName + rorSettingsFileName = rorConfigFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala index a27d43d113..cf02610ba4 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala @@ -77,7 +77,7 @@ class RemoteReindexSuite clusterSettingsCreator { SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = RemoteReindexSuite.this.rorConfigFileName, + rorSettingsFileName = RemoteReindexSuite.this.rorConfigFileName, restSsl = Enabled.No ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala index 8bb59420f7..892c3f05c3 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala @@ -41,7 +41,7 @@ class RorDisabledSuite EsClusterSettings.create( clusterName = "ROR1", securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorConfigFileName, )), ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index 3855dea9b8..ac910534f2 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -41,7 +41,7 @@ class RorStartingResponseCodeSuite extends AnyWordSpec with ESVersionSupportForA implicit val scheduler: Scheduler = Scheduler.computation(10) - private val validRorConfigFile = "/ror_starting_response_code/readonlyrest.yml" + private val validRorConfigFile = "/ror_starting_response_code/malformed_readonlyrest.yml" private val notStartedResponseCodeKey = "readonlyrest.not_started_response_code" @@ -143,7 +143,7 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { clusterName = clusterName, securityType = SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFile, + rorSettingsFileName = rorConfigFile, rorInIndexConfigLoadingDelay = 5 seconds ) ), diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala index e842d678d7..849da3ae98 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala @@ -29,7 +29,7 @@ class XpackApiWithRorWithEnabledXpackSecuritySuite extends BaseXpackApiSuite { override protected def rorClusterSecurityType: SecurityType = SecurityType.RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorConfigFileName, restSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.RestSsl.Xpack), internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )) diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala index 24971788b6..0d4075ad72 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/PatchingOfAptBasedEsInstallationSuite.scala @@ -211,7 +211,7 @@ private object PatchingOfAptBasedEsInstallationSuite extends EsModulePatterns { clusterName = clusterName, securityType = SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFile + rorSettingsFileName = rorConfigFile ) ), containerSpecification = ContainerSpecification.empty, diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala index 75513c2243..69ce367810 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala @@ -66,7 +66,7 @@ class ExampleEsWithRorContainer(implicit scheduler: Scheduler) extends EsContain val nodeName = s"${clusterName}_1" val attributes = ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( rorConfigReloading = Enabled.No, - rorConfigFileName = "/basic/readonlyrest.yml", + rorSettingsFileName = "/basic/readonlyrest.yml", ) createCustomES( nodeSettings = EsNodeSettings( @@ -90,7 +90,7 @@ class ExampleEsWithRorContainer(implicit scheduler: Scheduler) extends EsContain startedClusterDependencies: StartedClusterDependencies) = { val project = RorPluginGradleProject.fromSystemProperty val pluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin not assembled, build the plugin or run the test from Gradle")) - val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorConfigFileName) + val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) val adjustedRorConfig = RorConfigAdjuster.adjustUsingDependencies( source = rawRorConfigFile.toScala, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala index a3c2b8e5da..1091a28c8e 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala @@ -82,7 +82,7 @@ trait EsContainerCreator { additionalLogConsumer: Option[Consumer[OutputFrame]], awaitingReadyStrategy: AwaitingReadyStrategy) = { val rorPluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin file assembly failed")) - val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorConfigFileName) + val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) val adjustedRorConfig = RorConfigAdjuster.adjustUsingDependencies( source = rawRorConfigFile.toScala, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala index 45d52e2cd6..5852853b5f 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala @@ -35,7 +35,7 @@ object ReadonlyRestWithEnabledXpackSecurityPlugin { rorCustomSettingsIndex: Option[String], restSsl: Enabled[RestSsl], internodeSsl: Enabled[InternodeSsl], - rorConfigFileName: String) + rorSettingsFileName: String) object Attributes { val default: Attributes = Attributes( rorConfigReloading = ReadonlyRestPlugin.Config.Attributes.default.rorConfigReloading, @@ -43,7 +43,7 @@ object ReadonlyRestWithEnabledXpackSecurityPlugin { rorCustomSettingsIndex = ReadonlyRestPlugin.Config.Attributes.default.rorCustomSettingsIndex, restSsl = if(XpackSecurityPlugin.Config.Attributes.default.restSslEnabled) Enabled.Yes(RestSsl.Xpack) else Enabled.No, internodeSsl = if(XpackSecurityPlugin.Config.Attributes.default.internodeSslEnabled) Enabled.Yes(InternodeSsl.Xpack) else Enabled.No, - rorConfigFileName = "/basic/readonlyrest.yml" + rorSettingsFileName = "/basic/readonlyrest.yml" ) } @@ -101,7 +101,7 @@ class ReadonlyRestWithEnabledXpackSecurityPlugin(esVersion: String, config.attributes.rorCustomSettingsIndex, restSsl = createRorRestSsl(), internodeSsl = createRorInternodeSsl(), - config.attributes.rorConfigFileName + config.attributes.rorSettingsFileName ) ) } From b8bf1b31f00411a5a02f42dfbf90de12d02b48de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 8 Dec 2025 17:39:28 +0100 Subject: [PATCH 064/103] wip --- .../groovy/readonlyrest.plugin-common-conventions.gradle | 7 ++++--- ci/run-pipeline.sh | 2 +- core/build.gradle | 8 ++++---- development.md | 2 +- es67x/build.gradle | 2 +- es70x/build.gradle | 2 +- es710x/build.gradle | 2 +- es711x/build.gradle | 2 +- es714x/build.gradle | 2 +- es716x/build.gradle | 2 +- es717x/build.gradle | 2 +- es72x/build.gradle | 2 +- es73x/build.gradle | 2 +- es74x/build.gradle | 2 +- es77x/build.gradle | 2 +- es78x/build.gradle | 2 +- es79x/build.gradle | 2 +- es80x/build.gradle | 2 +- es810x/build.gradle | 2 +- es811x/build.gradle | 2 +- es812x/build.gradle | 2 +- es813x/build.gradle | 2 +- es814x/build.gradle | 2 +- es815x/build.gradle | 2 +- es816x/build.gradle | 2 +- es818x/build.gradle | 2 +- es81x/build.gradle | 2 +- es82x/build.gradle | 2 +- es83x/build.gradle | 2 +- es84x/build.gradle | 2 +- es85x/build.gradle | 2 +- es87x/build.gradle | 2 +- es88x/build.gradle | 2 +- es89x/build.gradle | 2 +- es90x/build.gradle | 2 +- es91x/build.gradle | 2 +- es92x/build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- ror-shadowed-libs/build.gradle | 2 +- ror-tools-core/build.gradle | 6 +++--- ror-tools/build.gradle | 6 +++--- tests-utils/build.gradle | 4 ++-- 42 files changed, 53 insertions(+), 52 deletions(-) diff --git a/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle b/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle index 51248c52d9..fe2f2649dd 100644 --- a/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle +++ b/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle @@ -82,9 +82,10 @@ tasks.withType(ScalaCompile).configureEach { ] } -tasks.withType(Zip).configureEach { task -> - task.doLast { - ant.checksum file: it.archivePath, algorithm: 'sha1' +tasks.withType(AbstractArchiveTask).configureEach { t -> + t.doLast { + def f = t.archiveFile.get().asFile + ant.checksum(file: f, algorithm: 'SHA-1', fileext: '.sha1') } } diff --git a/ci/run-pipeline.sh b/ci/run-pipeline.sh index 0144a03ab9..eda0cc3b6a 100755 --- a/ci/run-pipeline.sh +++ b/ci/run-pipeline.sh @@ -53,7 +53,7 @@ run_integration_tests() { ES_MODULE=$1 - echo ">>> $ES_MODULE => Running testcontainers.." + echo ">>> $ES_MODULE => Running integration tests.." ./gradlew --no-daemon ror-tools:test integration-tests:test "-PesModule=$ES_MODULE" || (find . | grep hs_err | xargs cat && exit 1) } diff --git a/core/build.gradle b/core/build.gradle index fe092ee5ba..11aefc4dd4 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -25,8 +25,8 @@ buildscript { plugins { id "readonlyrest.base-common-conventions" - id "com.github.johnrengelman.shadow" version "8.1.1" id "com.github.maiflai.scalatest" version "0.33" + id "com.gradleup.shadow" version "9.1.0" id "java-library" } @@ -101,7 +101,7 @@ dependencies { testImplementation group: 'org.scalamock', name: 'scalamock_3', version: '6.0.0' testImplementation group: 'org.scalatestplus', name: 'scalacheck-1-16_3', version: '3.2.14.0' testImplementation group: 'org.scalatest', name: 'scalatest_3', version: '3.2.16' - testImplementation group: 'com.dimafeng', name: 'testcontainers-scala-core_3', version: '0.41.4' + testImplementation group: 'com.dimafeng', name: 'testcontainers-scala-core_3', version: '0.44.0' constraints { api group: 'io.netty', name: 'netty-codec-http2', version: '4.1.126.Final' @@ -165,8 +165,8 @@ tasks.withType(ScalaCompile).configureEach { import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar tasks.named('shadowJar', ShadowJar) { - enableRelocation true - relocationPrefix "tech.beshu.ror" + enableAutoRelocation = true + relocationPrefix = "tech.beshu.ror" } tasks.withType(AbstractArchiveTask).configureEach { diff --git a/development.md b/development.md index a31af09d46..de57f3c1f7 100644 --- a/development.md +++ b/development.md @@ -47,7 +47,7 @@ Currently eshome support debugging only es8x modules. **⚠️Required tools:** * OpenJDK 21 -* Gradle 8.4 +* Gradle ### Using Docker * `./docker-based-builder/build.sh [ES_VERSION_1] [ES_VERSION_1] ... [ES_VERSION_N]` diff --git a/es67x/build.gradle b/es67x/build.gradle index cf21673cb9..1d4580de09 100644 --- a/es67x/build.gradle +++ b/es67x/build.gradle @@ -101,7 +101,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es70x/build.gradle b/es70x/build.gradle index e4d5d299d0..4e7b7af4f7 100644 --- a/es70x/build.gradle +++ b/es70x/build.gradle @@ -94,7 +94,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es710x/build.gradle b/es710x/build.gradle index a36653dc2d..808d8042b4 100644 --- a/es710x/build.gradle +++ b/es710x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es711x/build.gradle b/es711x/build.gradle index aacb91dd03..65eb04f442 100644 --- a/es711x/build.gradle +++ b/es711x/build.gradle @@ -97,7 +97,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es714x/build.gradle b/es714x/build.gradle index 0c6cd800fe..fa6e9952f4 100644 --- a/es714x/build.gradle +++ b/es714x/build.gradle @@ -94,7 +94,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es716x/build.gradle b/es716x/build.gradle index d0c9fbe623..dfe16e041c 100644 --- a/es716x/build.gradle +++ b/es716x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es717x/build.gradle b/es717x/build.gradle index d0c9fbe623..dfe16e041c 100644 --- a/es717x/build.gradle +++ b/es717x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es72x/build.gradle b/es72x/build.gradle index e4d5d299d0..4e7b7af4f7 100644 --- a/es72x/build.gradle +++ b/es72x/build.gradle @@ -94,7 +94,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es73x/build.gradle b/es73x/build.gradle index e4d5d299d0..4e7b7af4f7 100644 --- a/es73x/build.gradle +++ b/es73x/build.gradle @@ -94,7 +94,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es74x/build.gradle b/es74x/build.gradle index 3c7f162515..5fd35ee10c 100644 --- a/es74x/build.gradle +++ b/es74x/build.gradle @@ -102,7 +102,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es77x/build.gradle b/es77x/build.gradle index 1f117b851d..b6dd048b4d 100644 --- a/es77x/build.gradle +++ b/es77x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es78x/build.gradle b/es78x/build.gradle index a36653dc2d..808d8042b4 100644 --- a/es78x/build.gradle +++ b/es78x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es79x/build.gradle b/es79x/build.gradle index a36653dc2d..808d8042b4 100644 --- a/es79x/build.gradle +++ b/es79x/build.gradle @@ -95,7 +95,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es80x/build.gradle b/es80x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es80x/build.gradle +++ b/es80x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es810x/build.gradle b/es810x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es810x/build.gradle +++ b/es810x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es811x/build.gradle b/es811x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es811x/build.gradle +++ b/es811x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es812x/build.gradle b/es812x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es812x/build.gradle +++ b/es812x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es813x/build.gradle b/es813x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es813x/build.gradle +++ b/es813x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es814x/build.gradle b/es814x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es814x/build.gradle +++ b/es814x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es815x/build.gradle b/es815x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es815x/build.gradle +++ b/es815x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es816x/build.gradle b/es816x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es816x/build.gradle +++ b/es816x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es818x/build.gradle b/es818x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es818x/build.gradle +++ b/es818x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es81x/build.gradle b/es81x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es81x/build.gradle +++ b/es81x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es82x/build.gradle b/es82x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es82x/build.gradle +++ b/es82x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es83x/build.gradle b/es83x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es83x/build.gradle +++ b/es83x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es84x/build.gradle b/es84x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es84x/build.gradle +++ b/es84x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es85x/build.gradle b/es85x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es85x/build.gradle +++ b/es85x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es87x/build.gradle b/es87x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es87x/build.gradle +++ b/es87x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es88x/build.gradle b/es88x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es88x/build.gradle +++ b/es88x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es89x/build.gradle b/es89x/build.gradle index db505e95c2..79196dcd0b 100644 --- a/es89x/build.gradle +++ b/es89x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es90x/build.gradle b/es90x/build.gradle index 6d354330d3..4028b6a7bd 100644 --- a/es90x/build.gradle +++ b/es90x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es91x/build.gradle b/es91x/build.gradle index 6d354330d3..4028b6a7bd 100644 --- a/es91x/build.gradle +++ b/es91x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/es92x/build.gradle b/es92x/build.gradle index 6d354330d3..4028b6a7bd 100644 --- a/es92x/build.gradle +++ b/es92x/build.gradle @@ -96,7 +96,7 @@ tasks.register('buildRorPluginZip') { tasks.register('packageRorPlugin', Zip) { dependsOn(cleanOldData, jarHellCheck, toJar, resolvePluginDescriptorTemplate) outputs.upToDateWhen { false } - archivesBaseName = pluginName + archiveBaseName = pluginName into('.') { from configurations.distJars.filter { x -> !x.name.contains('spatial4j') && !x.name.contains('jts') } from 'build/libs/' + pluginFullName + '.jar' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 711ebf5e38..472e5d5117 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-all.zip \ No newline at end of file diff --git a/ror-shadowed-libs/build.gradle b/ror-shadowed-libs/build.gradle index a6f795cced..4177e35083 100644 --- a/ror-shadowed-libs/build.gradle +++ b/ror-shadowed-libs/build.gradle @@ -18,7 +18,7 @@ plugins { id "readonlyrest.base-common-conventions" - id "com.gradleup.shadow" version "9.0.1" + id "com.gradleup.shadow" version "9.1.0" id "java" id "maven-publish" } diff --git a/ror-tools-core/build.gradle b/ror-tools-core/build.gradle index 6919910bbd..7c4326bb11 100644 --- a/ror-tools-core/build.gradle +++ b/ror-tools-core/build.gradle @@ -17,7 +17,7 @@ plugins { id "readonlyrest.base-common-conventions" - id "com.github.johnrengelman.shadow" version "8.1.1" + id "com.gradleup.shadow" version "9.1.0" id "com.github.maiflai.scalatest" version "0.33" id "java-library" } @@ -81,8 +81,8 @@ shadowJar { import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar tasks.named('shadowJar', ShadowJar) { - enableRelocation true - relocationPrefix "tech.beshu.ror.tools" + enableAutoRelocation = true + relocationPrefix = "tech.beshu.ror.tools" } tasks.withType(AbstractArchiveTask).configureEach { diff --git a/ror-tools/build.gradle b/ror-tools/build.gradle index 701dbbef36..84b5163e50 100644 --- a/ror-tools/build.gradle +++ b/ror-tools/build.gradle @@ -23,8 +23,8 @@ buildscript { plugins { id "readonlyrest.base-common-conventions" - id "com.github.johnrengelman.shadow" version "8.1.1" id "com.github.maiflai.scalatest" version "0.33" + id "com.gradleup.shadow" version "9.1.0" } repositories { @@ -110,8 +110,8 @@ shadowJar { import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar tasks.named('shadowJar', ShadowJar) { - enableRelocation true - relocationPrefix "tech.beshu.ror.tools" + enableAutoRelocation = true + relocationPrefix = "tech.beshu.ror.tools" } tasks.withType(AbstractArchiveTask).configureEach { diff --git a/tests-utils/build.gradle b/tests-utils/build.gradle index 3622843868..ac4884a540 100644 --- a/tests-utils/build.gradle +++ b/tests-utils/build.gradle @@ -74,8 +74,8 @@ dependencies { api group: 'org.scala-lang.modules' , name: 'scala-parallel-collections_3', version: '1.0.4' api group: 'com.typesafe.scala-logging', name: 'scala-logging_3', version: '3.9.5' api group: 'org.scalatest', name: 'scalatest_3', version: '3.2.19' - api group: 'com.dimafeng', name: 'testcontainers-scala-scalatest_3', version: '0.43.0' - api group: 'org.testcontainers', name: 'testcontainers', version: "1.20.6" + api group: 'com.dimafeng', name: 'testcontainers-scala-scalatest_3', version: '0.44.0' + api group: 'org.testcontainers', name: 'testcontainers', version: "2.0.2" api group: 'eu.rekawek.toxiproxy', name: 'toxiproxy-java', version: "2.1.7" api group: 'com.unboundid', name: 'unboundid-ldapsdk', version: '6.0.11' api group: 'com.lihaoyi', name: 'upickle_3', version: '4.2.1' From 4e196a49dca22f2cd0aa2f1dc586010ec5c2bdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 8 Dec 2025 20:08:27 +0100 Subject: [PATCH 065/103] wip --- .../ror/integration/suites/ActionsSuite.scala | 2 +- .../suites/AdminApiAuthMockSuite.scala | 41 +++++++++++-------- .../AdminApiWithDefaultRorIndexSuite.scala | 8 ++-- .../ror/integration/suites/CatApiSuite.scala | 2 +- .../suites/ClosedIndicesSuite.scala | 2 +- .../integration/suites/ClusterApiSuite.scala | 4 +- .../suites/CrossClusterCallsSuite.scala | 6 +-- .../suites/CurrentUserMetadataSuite.scala | 2 +- .../suites/DataStreamApiSuite.scala | 2 +- .../suites/DeleteByQuerySuite.scala | 2 +- .../integration/suites/DocumentApiSuite.scala | 2 +- .../DuplicatedResponseHeadersIssueSuite.scala | 2 +- .../suites/DynamicVariablesSuite.scala | 4 +- .../suites/ExternalAuthenticationSuite.scala | 2 +- .../integration/suites/FilterRuleSuite.scala | 2 +- .../FiltersAndFieldsSecuritySuite.scala | 2 +- .../suites/FiltersDocLevelSecuritySuite.scala | 2 +- .../ror/integration/suites/FipsSslSuite.scala | 4 +- .../integration/suites/HostsRuleSuite.scala | 2 +- .../suites/ImpersonationSuite.scala | 4 +- .../suites/IndexAliasesManagementSuite.scala | 2 +- .../IndexApiWithFreeKibanaSupportSuite.scala | 2 +- ...ndexApiWithNonFreeKibanaSupportSuite.scala | 2 +- .../IndexLifecycleManagementApiSuite.scala | 4 +- .../IndexTemplatesManagementSuite.scala | 2 +- .../suites/IndicesReverseWildcardSuite.scala | 2 +- .../ror/integration/suites/JwtAuthSuite.scala | 2 +- .../suites/LdapIntegrationSuite.scala | 2 +- .../integration/suites/LocalGroupsSuite.scala | 2 +- .../suites/MSearchTEST1Suite.scala | 2 +- .../suites/MSearchTEST2Suite.scala | 2 +- .../suites/MSearchTEST3Suite.scala | 2 +- .../suites/MSearchWithFilterSuite.scala | 2 +- .../ror/integration/suites/MiscSuite.scala | 2 +- .../ror/integration/suites/ReindexSuite.scala | 2 +- .../suites/RemoteReindexSuite.scala | 6 +-- .../suites/ResponseFieldRuleSuite.scala | 2 +- ...WithGroupsProviderAuthorizationSuite.scala | 2 +- .../integration/suites/RorDisabledSuite.scala | 4 +- .../integration/suites/RorKbnAuthSuite.scala | 2 +- .../suites/RorStartingResponseCodeSuite.scala | 2 +- .../integration/suites/SearchApiSuite.scala | 2 +- .../suites/ShrinkIndexApiSuite.scala | 2 +- .../suites/SnapshotAndRestoreApiSuite.scala | 2 +- .../suites/SplitIndexApiSuite.scala | 2 +- .../suites/UriRegexRuleSuite.scala | 2 +- ...ithRorWithDisabledXpackSecuritySuite.scala | 4 +- ...WithRorWithEnabledXpackSecuritySuite.scala | 4 +- ...RorNodesAndInternodeSslKeystoreSuite.scala | 2 +- ...rWithRorNodesAndInternodeSslPemSuite.scala | 2 +- .../audit/DisabledAuditingToolsSuite.scala | 2 +- .../LocalClusterAuditingToolsSuite.scala | 6 +-- .../audit/QueryAuditLogSerializerSuite.scala | 2 +- .../RemoteClusterAuditingToolsSuite.scala | 4 +- ...sterWithRorNodesAndInternodeSslSuite.scala | 2 +- .../ror/integration/suites/base/support.scala | 8 ++-- .../engine/FieldRuleEsEngineSuite.scala | 2 +- .../FieldRuleEsWithLuceneEngineSuite.scala | 2 +- .../engine/FieldRuleLuceneEngineSuite.scala | 2 +- .../querydsl/FieldRuleQueryDSLSuite.scala | 2 +- .../FieldRuleSourceFilteringSuite.scala | 2 +- .../integration/utils/PluginTestSupport.scala | 20 ++++----- .../utils/ExampleEsWithRorContainer.scala | 6 +-- .../utils/containers/EsClusterContainer.scala | 4 +- .../utils/containers/EsContainerCreator.scala | 16 ++++---- ...juster.scala => RorSettingsAdjuster.scala} | 10 ++--- .../SingletonEsContainerWithRorSecurity.scala | 4 +- .../images/ReadonlyRestPlugin.scala | 26 ++++++------ ...lyRestWithEnabledXpackSecurityPlugin.scala | 16 ++++---- .../ror/utils/containers/providers.scala | 8 ++-- 70 files changed, 159 insertions(+), 154 deletions(-) rename tests-utils/src/main/scala/tech/beshu/ror/utils/containers/{RorConfigAdjuster.scala => RorSettingsAdjuster.scala} (90%) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ActionsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ActionsSuite.scala index da97abfb79..e69daf7942 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ActionsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ActionsSuite.scala @@ -31,7 +31,7 @@ class ActionsSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/actions/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/actions/readonlyrest.yml" override val nodeDataInitializer = Some { (esVersion, adminRestClient: RestClient) => { val documentManager = new DocumentManager(adminRestClient, esVersion) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index af11b358a4..ec457fb53f 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -52,7 +52,7 @@ class AdminApiAuthMockSuite override lazy val clusterContainers = NonEmptyList.of(esCluster) override lazy val esTargets = NonEmptyList.fromListUnsafe(esCluster.nodes) - override implicit val rorConfigFileName: String = "/admin_api_mocks/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/admin_api_mocks/readonlyrest.yml" private val readonlyrestIndexName = ".readonlyrest" @@ -69,9 +69,9 @@ class AdminApiAuthMockSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigReloading = Enabled.Yes(2 seconds), + rorSettingsReloading = Enabled.Yes(2 seconds), rorCustomSettingsIndex = Some(readonlyrestIndexName), - rorSettingsFileName = rorConfigFileName + rorSettingsFileName = rorSettingsFileName )) ), ) @@ -1241,15 +1241,18 @@ class AdminApiAuthMockSuite eventually { // await until all nodes load config rorClients.foreach { - assertTestSettings(_, expectedStatus = "TEST_SETTINGS_INVALIDATED") + assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_INVALIDATED") } } } - private def assertTestSettings(rorApiManager: RorApiManager, expectedStatus: String) = { + private def assertCurrentTestSettings(rorApiManager: RorApiManager, expectedStatus: String, otherExpectedStatuses: String*) = { val response = rorApiManager.currentRorTestSettings + val expectedStatuses = expectedStatus :: otherExpectedStatuses.toList response should have statusCode 200 - response.responseJson("status").str should be(expectedStatus) + + val status = response.responseJson("status").str + expectedStatuses should contain (status) } private def updateMocksPayload(payloadServices: Value) = { @@ -1263,7 +1266,7 @@ class AdminApiAuthMockSuite ) } - private def testEngineConfig(): String = esCluster.resolvedRorConfig(getResourceContent(rorConfigFileName)) + private def testEngineSettings(): String = esCluster.resolvedRorSettings(getResourceContent(rorSettingsFileName)) override implicit val patienceConfig: PatienceConfig = PatienceConfig(timeout = testEngineReloadInterval.plus(10 second), interval = 500 millis) @@ -1279,19 +1282,19 @@ class AdminApiAuthMockSuite } private def removeRorIndexAndAwaitForNotSetTestConfig(): Unit = { - // remove index storing test config + // remove index storing test settings new IndexManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) .removeIndex(readonlyrestIndexName) - eventually { // await until node invalidate the test config + eventually { // await until node invalidate the test settings rorClients.foreach { - assertTestSettings(_, expectedStatus = "TEST_SETTINGS_NOT_CONFIGURED") + assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_NOT_CONFIGURED", otherExpectedStatuses = "TEST_SETTINGS_INVALIDATED") } } } private def setupTestSettingsInIndex(mocksJson: Value) = { - val testSettings = testEngineConfig() + val testSettings = testEngineSettings() val expirationTtl = 30 minutes val expirationTime = Instant.now().plus(expirationTtl.toMillis, ChronoUnit.MILLIS) val testSettingsJson = ujson.read( @@ -1316,22 +1319,24 @@ class AdminApiAuthMockSuite indexSearchResponse should have statusCode 200 val indexSearchHits = indexSearchResponse.responseJson("hits")("hits").arr.toList indexSearchHits.size should be >= 1 // at least main document or test document should be present - val testSettingsDocumentHit = indexSearchHits.find { searchResult => - (searchResult("_index").str, searchResult("_id").str) === (readonlyrestIndexName, testSettingsEsDocumentId) - }.value + val testSettingsDocumentHit = indexSearchHits + .find { searchResult => + (searchResult("_index").str, searchResult("_id").str) === (readonlyrestIndexName, testSettingsEsDocumentId) + } + .value - val mocksContent = ujson.read(testSettingsDocumentHit("_source")("auth_services_mocks").str) + val mocksContent = testSettingsDocumentHit("_source")("auth_services_mocks") mocksContent should be(expectedMocks) } private def setupTestSettingsOnAllNodes(): Unit = { rorClients.head - .updateRorTestSettings(testEngineConfig()) + .updateRorTestSettings(testEngineSettings()) .forceOkStatus() - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { - assertTestSettings(_, expectedStatus = "TEST_SETTINGS_PRESENT") + assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_PRESENT") } } } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala index 276caea870..d11c11c57d 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala @@ -28,7 +28,7 @@ class AdminApiWithDefaultRorIndexSuite extends BaseAdminApiSuite with PluginTestSupport { - override implicit val rorConfigFileName: String = "/admin_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/admin_api/readonlyrest.yml" override protected val readonlyrestIndexName: String = ".readonlyrest" override protected lazy val rorWithIndexConfig: EsClusterContainer = { @@ -43,8 +43,8 @@ class AdminApiWithDefaultRorIndexSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName, - rorConfigReloading = Enabled.Yes(settingsReloadInterval) + rorSettingsFileName = rorSettingsFileName, + rorSettingsReloading = Enabled.Yes(settingsReloadInterval) )) ) ) @@ -60,7 +60,7 @@ class AdminApiWithDefaultRorIndexSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName + rorSettingsFileName = rorSettingsFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CatApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CatApiSuite.scala index f700405df6..04271c39e7 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CatApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CatApiSuite.scala @@ -31,7 +31,7 @@ class CatApiSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/cat_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/cat_api/readonlyrest.yml" private lazy val dev1CatManager = new CatManager(basicAuthClient("dev1", "test"), esVersion = esVersionUsed) private lazy val dev2CatManager = new CatManager(basicAuthClient("dev2", "test"), esVersion = esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClosedIndicesSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClosedIndicesSuite.scala index d8b2b959c2..b28eee05e0 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClosedIndicesSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClosedIndicesSuite.scala @@ -31,7 +31,7 @@ class ClosedIndicesSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/closed_indices/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/closed_indices/readonlyrest.yml" override val nodeDataInitializer = Some { (esVersion, adminRestClient: RestClient) => { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala index 30d6d9f33f..ce8ac353db 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ClusterApiSuite.scala @@ -36,7 +36,7 @@ class ClusterApiSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/cluster_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/cluster_api/readonlyrest.yml" override lazy val targetEs = container.nodes.head override lazy val clusterContainer: EsClusterContainer = { @@ -50,7 +50,7 @@ class ClusterApiSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName + rorSettingsFileName = rorSettingsFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala index 0ae6b67c33..d97b5ab44a 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CrossClusterCallsSuite.scala @@ -46,7 +46,7 @@ class CrossClusterCallsSuite import tech.beshu.ror.integration.suites.CrossClusterCallsSuite.* - override implicit val rorConfigFileName: String = "/cross_cluster_search/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/cross_cluster_search/readonlyrest.yml" override lazy val targetEs = container.localCluster.nodes.head @@ -54,7 +54,7 @@ class CrossClusterCallsSuite esClusterSettings = EsClusterSettings.create( clusterName = "ROR_L1", securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )), nodeDataInitializer = localClusterNodeDataInitializer(), @@ -80,7 +80,7 @@ class CrossClusterCallsSuite EsClusterSettings.create( clusterName = name, securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )), nodeDataInitializer = nodeDataInitializer diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CurrentUserMetadataSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CurrentUserMetadataSuite.scala index ca8617ae80..9c339395ee 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CurrentUserMetadataSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/CurrentUserMetadataSuite.scala @@ -32,7 +32,7 @@ class CurrentUserMetadataSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/current_user_metadata/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/current_user_metadata/readonlyrest.yml" "An ACL" when { "handling current user metadata kibana plugin request (without ROR metadata)" should { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DataStreamApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DataStreamApiSuite.scala index 3d7819501a..2af81bff2b 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DataStreamApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DataStreamApiSuite.scala @@ -38,7 +38,7 @@ class DataStreamApiSuite with BeforeAndAfterEach with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/data_stream_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/data_stream_api/readonlyrest.yml" private lazy val client = clients.head.adminClient private lazy val user1Client = clients.head.basicAuthClient("user1", "pass") diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DeleteByQuerySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DeleteByQuerySuite.scala index 17c1ad8b24..87869fb6df 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DeleteByQuerySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DeleteByQuerySuite.scala @@ -32,7 +32,7 @@ class DeleteByQuerySuite private val matchAllQuery = ujson.read("""{"query" : {"match_all" : {}}}""".stripMargin) - override implicit val rorConfigFileName: String = "/delete_by_query/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/delete_by_query/readonlyrest.yml" override def nodeDataInitializer = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DocumentApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DocumentApiSuite.scala index 4535c3a26e..3f827071f7 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DocumentApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DocumentApiSuite.scala @@ -34,7 +34,7 @@ class DocumentApiSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/document_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/document_api/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(DocumentApiSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DuplicatedResponseHeadersIssueSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DuplicatedResponseHeadersIssueSuite.scala index 2da23359f4..33253a1fba 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DuplicatedResponseHeadersIssueSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DuplicatedResponseHeadersIssueSuite.scala @@ -34,7 +34,7 @@ class DuplicatedResponseHeadersIssueSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/duplicated_response_headers_issue/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/duplicated_response_headers_issue/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala index c21215c0fe..eb61722673 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/DynamicVariablesSuite.scala @@ -34,7 +34,7 @@ class DynamicVariablesSuite with SingleClientSupport with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/dynamic_vars/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/dynamic_vars/readonlyrest.yml" override lazy val targetEs = container.nodes.head @@ -54,7 +54,7 @@ class DynamicVariablesSuite createLocalClusterContainer( esClusterSettingsCreator( SecurityType.RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName + rorSettingsFileName = rorSettingsFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ExternalAuthenticationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ExternalAuthenticationSuite.scala index 02f7500182..da76c4be4e 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ExternalAuthenticationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ExternalAuthenticationSuite.scala @@ -32,7 +32,7 @@ class ExternalAuthenticationSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/external_authentication/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/external_authentication/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FilterRuleSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FilterRuleSuite.scala index edbffeb87d..6b05a11dbc 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FilterRuleSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FilterRuleSuite.scala @@ -34,7 +34,7 @@ class FilterRuleSuite with SingleClientSupport with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/filter_rules/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/filter_rules/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(FilterRuleSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersAndFieldsSecuritySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersAndFieldsSecuritySuite.scala index 3e4686fcd6..f152227260 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersAndFieldsSecuritySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersAndFieldsSecuritySuite.scala @@ -33,7 +33,7 @@ class FiltersAndFieldsSecuritySuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/fls_dls/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/fls_dls/readonlyrest.yml" override def nodeDataInitializer = Some(FiltersAndFieldsSecuritySuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersDocLevelSecuritySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersDocLevelSecuritySuite.scala index 22b12a3a54..1330805d32 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersDocLevelSecuritySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FiltersDocLevelSecuritySuite.scala @@ -34,7 +34,7 @@ class FiltersDocLevelSecuritySuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/filters/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/filters/readonlyrest.yml" override def nodeDataInitializer = Some(FiltersDocLevelSecuritySuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala index 7f0c865e84..adac2742ea 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala @@ -38,7 +38,7 @@ class FipsSslSuite with BeforeAndAfterAll with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/fips_ssl/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/fips_ssl/readonlyrest.yml" override def clusterContainer: EsClusterContainer = generalClusterContainer @@ -49,7 +49,7 @@ class FipsSslSuite clusterName = "fips_cluster", numberOfInstances = positiveInt(2), securityType = RorSecurity(Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, restSsl = Enabled.Yes(RestSsl.RorFips(SourceFile.RorFile)), internodeSsl = Enabled.Yes(InternodeSsl.RorFips(SourceFile.RorFile)) )) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/HostsRuleSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/HostsRuleSuite.scala index 03e5e9ec0e..18bca21629 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/HostsRuleSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/HostsRuleSuite.scala @@ -33,7 +33,7 @@ class HostsRuleSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/hosts_rule/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/hosts_rule/readonlyrest.yml" override def nodeDataInitializer = Some(HostsRuleSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala index aa4fd801b8..1b46e1c011 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala @@ -38,7 +38,7 @@ class ImpersonationSuite with BeforeAndAfterAll with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/impersonation/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/impersonation/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(ImpersonationSuite.nodeDataInitializer()) @@ -699,7 +699,7 @@ class ImpersonationSuite private def loadTestSettings(): Unit = { rorApiManager - .updateRorTestSettings(resolvedRorConfigFile.contentAsString) + .updateRorTestSettings(resolvedRorSettingsFile.contentAsString) .forceOkStatus() } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexAliasesManagementSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexAliasesManagementSuite.scala index 0c02b877af..f8a7723caf 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexAliasesManagementSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexAliasesManagementSuite.scala @@ -33,7 +33,7 @@ class IndexAliasesManagementSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/aliases/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/aliases/readonlyrest.yml" private lazy val adminDocumentManager = new DocumentManager(basicAuthClient("admin", "container"), esVersionUsed) private lazy val adminIndexManager = new IndexManager(basicAuthClient("admin", "container"), esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithFreeKibanaSupportSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithFreeKibanaSupportSuite.scala index f9f09c6043..16193d3119 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithFreeKibanaSupportSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithFreeKibanaSupportSuite.scala @@ -24,7 +24,7 @@ class IndexApiWithFreeKibanaSupportSuite extends BaseIndexApiSuite with SingletonPluginTestSupport { - override implicit val rorConfigFileName: String = "/index_api/free_readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/index_api/free_readonlyrest.yml" override val notFoundIndexStatusReturned: Int = 401 override val forbiddenStatusReturned: Int = 401 diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithNonFreeKibanaSupportSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithNonFreeKibanaSupportSuite.scala index b5ee37aaa8..4f42189853 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithNonFreeKibanaSupportSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexApiWithNonFreeKibanaSupportSuite.scala @@ -24,7 +24,7 @@ class IndexApiWithNonFreeKibanaSupportSuite extends BaseIndexApiSuite with SingletonPluginTestSupport { - override implicit val rorConfigFileName: String = "/index_api/nonfree_readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/index_api/nonfree_readonlyrest.yml" override val notFoundIndexStatusReturned: Int = 404 override val forbiddenStatusReturned: Int = 403 diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala index 2a1cdb32b1..36347f40ba 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexLifecycleManagementApiSuite.scala @@ -47,7 +47,7 @@ class IndexLifecycleManagementApiSuite with CustomScalaTestMatchers with Eventually { - override implicit val rorConfigFileName: String = "/index_lifecycle_management_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/index_lifecycle_management_api/readonlyrest.yml" override lazy val targetEs = container.nodes.head @@ -62,7 +62,7 @@ class IndexLifecycleManagementApiSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName + rorSettingsFileName = rorSettingsFileName )) ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexTemplatesManagementSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexTemplatesManagementSuite.scala index ee14fe34d0..a3b963ec94 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexTemplatesManagementSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndexTemplatesManagementSuite.scala @@ -34,7 +34,7 @@ class IndexTemplatesManagementSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/templates/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/templates/readonlyrest.yml" indexTemplateApiTests("A legacy template API")(new LegacyTemplateManager(_, esVersionUsed)) if (doesSupportIndexTemplates) indexTemplateApiTests("A new template API")(new IndexTemplateManager(_, esVersionUsed)) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndicesReverseWildcardSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndicesReverseWildcardSuite.scala index ed1422b79f..93a775c46c 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndicesReverseWildcardSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/IndicesReverseWildcardSuite.scala @@ -32,7 +32,7 @@ class IndicesReverseWildcardSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/indices_reverse_wildcards/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/indices_reverse_wildcards/readonlyrest.yml" override def nodeDataInitializer = Some(IndicesReverseWildcardSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/JwtAuthSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/JwtAuthSuite.scala index 18e129449c..d11eb2d868 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/JwtAuthSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/JwtAuthSuite.scala @@ -41,7 +41,7 @@ class JwtAuthSuite private val validKeyRole = "1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890" private val wrongKey = "abcdefdsadsadsafdsfsadasdfdsfdfdsfdsfsadsdsaffds" - override implicit val rorConfigFileName: String = "/jwt_auth/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/jwt_auth/readonlyrest.yml" "rejectRequestWithoutAuthorizationHeader" in { val clusterStateManager = new CatManager(noBasicAuthClient, esVersion = esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LdapIntegrationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LdapIntegrationSuite.scala index 14a1e969c8..b01a10a0f8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LdapIntegrationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LdapIntegrationSuite.scala @@ -33,7 +33,7 @@ class LdapIntegrationSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/ldap_integration/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/ldap_integration/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(LdapIntegrationSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LocalGroupsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LocalGroupsSuite.scala index 3a94c1e0fc..a90a828d06 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LocalGroupsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/LocalGroupsSuite.scala @@ -35,7 +35,7 @@ class LocalGroupsSuite with Matchers with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/local_groups/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/local_groups/readonlyrest.yml" "good credentials but with non matching preferred group are sent" in { val clusterManager = new ClusterManager( diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST1Suite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST1Suite.scala index 577f4e50ad..caa991ae04 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST1Suite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST1Suite.scala @@ -50,7 +50,7 @@ class MSearchTEST1Suite val msearchBodyCombo = msearchBodyNotExists ++ msearchBodyQueryWorks ++ msearchBodyEmptyIndex - override implicit val rorConfigFileName: String = "/msearch_test1/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/msearch_test1/readonlyrest.yml" override def nodeDataInitializer = Some(MSearchTEST1Suite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST2Suite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST2Suite.scala index 45eabcecf4..f8c0cad234 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST2Suite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST2Suite.scala @@ -50,7 +50,7 @@ class MSearchTEST2Suite private val msearchBodyCombo = msearchBodyNoMatch ++ msearchBroken ++ msearchBodyEmptyIndex - override implicit val rorConfigFileName: String = "/msearch_test2/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/msearch_test2/readonlyrest.yml" override def nodeDataInitializer = Some(MSearchTEST2Suite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST3Suite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST3Suite.scala index 642148c1f9..be65738a77 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST3Suite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchTEST3Suite.scala @@ -38,7 +38,7 @@ class MSearchTEST3Suite """{"version":true,"size":0,"query":{"match_all":{}}}""" ) - override implicit val rorConfigFileName: String = "/msearch_test3/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/msearch_test3/readonlyrest.yml" override def nodeDataInitializer = Some(MSearchTEST3Suite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchWithFilterSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchWithFilterSuite.scala index a70a64f522..7a2313b60a 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchWithFilterSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MSearchWithFilterSuite.scala @@ -34,7 +34,7 @@ class MSearchWithFilterSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/msearch_with_filter/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/msearch_with_filter/readonlyrest.yml" override def nodeDataInitializer = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MiscSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MiscSuite.scala index 87585753cd..9dcae5e5a3 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MiscSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/MiscSuite.scala @@ -33,7 +33,7 @@ class MiscSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/misc/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/misc/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(MiscSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReindexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReindexSuite.scala index 048dfac35f..94f384efea 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReindexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReindexSuite.scala @@ -33,7 +33,7 @@ class ReindexSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/reindex/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/reindex/readonlyrest.yml" override def nodeDataInitializer = Some(ReindexSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala index cf02610ba4..348bf0ba00 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala @@ -41,7 +41,7 @@ class RemoteReindexSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/reindex_multi_containers/readonlyrest_dest_es.yml" + override implicit val rorSettingsFileName: String = "/reindex_multi_containers/readonlyrest_dest_es.yml" private val sourceEsRorConfigFileName = "/reindex_multi_containers/readonlyrest_source_es.yml" private lazy val sourceEsCluster = createLocalClusterContainer( @@ -56,7 +56,7 @@ class RemoteReindexSuite }, securityType = SecurityType.RorSecurity( ReadonlyRestPlugin.Config.Attributes.default.copy( - rorConfigFileName = RemoteReindexSuite.this.sourceEsRorConfigFileName, + rorSettingsFileName = RemoteReindexSuite.this.sourceEsRorConfigFileName, restSsl = Enabled.No )) ) @@ -77,7 +77,7 @@ class RemoteReindexSuite clusterSettingsCreator { SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = RemoteReindexSuite.this.rorConfigFileName, + rorSettingsFileName = RemoteReindexSuite.this.rorSettingsFileName, restSsl = Enabled.No ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ResponseFieldRuleSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ResponseFieldRuleSuite.scala index 84be0d8e60..f148e0a720 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ResponseFieldRuleSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ResponseFieldRuleSuite.scala @@ -32,7 +32,7 @@ class ResponseFieldRuleSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/response_field_rules/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/response_field_rules/readonlyrest.yml" override def nodeDataInitializer = Some(ResponseFieldRuleSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReverseProxyAuthenticationWithGroupsProviderAuthorizationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReverseProxyAuthenticationWithGroupsProviderAuthorizationSuite.scala index 97d2545767..022afae383 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReverseProxyAuthenticationWithGroupsProviderAuthorizationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ReverseProxyAuthenticationWithGroupsProviderAuthorizationSuite.scala @@ -32,7 +32,7 @@ class ReverseProxyAuthenticationWithGroupsProviderAuthorizationSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/rev_proxy_groups_provider/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/rev_proxy_groups_provider/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala index 892c3f05c3..7898453e71 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorDisabledSuite.scala @@ -33,7 +33,7 @@ class RorDisabledSuite with SingleClientSupport with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/plugin_disabled/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/plugin_disabled/readonlyrest.yml" override lazy val targetEs = container.nodes.head @@ -41,7 +41,7 @@ class RorDisabledSuite EsClusterSettings.create( clusterName = "ROR1", securityType = RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, )), ) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorKbnAuthSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorKbnAuthSuite.scala index c324fd9d20..124c557caa 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorKbnAuthSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorKbnAuthSuite.scala @@ -37,7 +37,7 @@ class RorKbnAuthSuite private val validKeyRole = "1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890" private val wrongKey = "abcdefdsadsadsadsadsadfdsfdsfdsfdsfds" - override implicit val rorConfigFileName: String = "/ror_kbn_auth/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/ror_kbn_auth/readonlyrest.yml" "rejectRequestWithoutAuthorizationHeader" in { val clusterStateManager = new CatManager(noBasicAuthClient, esVersion = esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index ac910534f2..61ce37115c 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -144,7 +144,7 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { securityType = SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( rorSettingsFileName = rorConfigFile, - rorInIndexConfigLoadingDelay = 5 seconds + rorInIndexSettingsLoadingDelay = 5 seconds ) ), containerSpecification = ContainerSpecification.empty.copy( diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SearchApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SearchApiSuite.scala index 92dc8589dc..7ff1a96791 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SearchApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SearchApiSuite.scala @@ -39,7 +39,7 @@ class SearchApiSuite with IntegrationPatience with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/search_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/search_api/readonlyrest.yml" override def nodeDataInitializer = Some(SearchApiSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ShrinkIndexApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ShrinkIndexApiSuite.scala index cbfd5dbc70..b68860db0e 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ShrinkIndexApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ShrinkIndexApiSuite.scala @@ -32,7 +32,7 @@ class ShrinkIndexApiSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/shrink_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/shrink_api/readonlyrest.yml" private lazy val user1IndexManager = new IndexManager(basicAuthClient("dev1", "test"), esVersionUsed) private lazy val user2IndexManager = new IndexManager(basicAuthClient("dev2", "test"), esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SnapshotAndRestoreApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SnapshotAndRestoreApiSuite.scala index db3731677a..badaaa7187 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SnapshotAndRestoreApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SnapshotAndRestoreApiSuite.scala @@ -40,7 +40,7 @@ class SnapshotAndRestoreApiSuite with CustomScalaTestMatchers with ESVersionSupportForAnyWordSpecLike { - override implicit val rorConfigFileName: String = "/snapshot_and_restore_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/snapshot_and_restore_api/readonlyrest.yml" override def nodeDataInitializer = Some(SnapshotAndRestoreApiSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SplitIndexApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SplitIndexApiSuite.scala index 7cb4f5277a..b4520a2fd5 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SplitIndexApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/SplitIndexApiSuite.scala @@ -32,7 +32,7 @@ class SplitIndexApiSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/split_api/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/split_api/readonlyrest.yml" private lazy val user1IndexManager = new IndexManager(basicAuthClient("dev1", "test"), esVersionUsed) private lazy val user2IndexManager = new IndexManager(basicAuthClient("dev2", "test"), esVersionUsed) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/UriRegexRuleSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/UriRegexRuleSuite.scala index 5c654a6b44..0fe42ecf55 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/UriRegexRuleSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/UriRegexRuleSuite.scala @@ -29,7 +29,7 @@ class UriRegexRuleSuite with ESVersionSupportForAnyWordSpecLike with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/uri_regex_rules/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/uri_regex_rules/readonlyrest.yml" "A uri rule" should { "allow health check" when { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithDisabledXpackSecuritySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithDisabledXpackSecuritySuite.scala index cae7e3ace3..cfffacaf05 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithDisabledXpackSecuritySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithDisabledXpackSecuritySuite.scala @@ -25,11 +25,11 @@ import tech.beshu.ror.utils.containers.images.domain.{Enabled, SourceFile} class XpackApiWithRorWithDisabledXpackSecuritySuite extends BaseXpackApiSuite { - override implicit val rorConfigFileName: String = "/xpack_api/readonlyrest_with_ror_ssl.yml" + override implicit val rorSettingsFileName: String = "/xpack_api/readonlyrest_with_ror_ssl.yml" override protected def rorClusterSecurityType: SecurityType = SecurityType.RorSecurity(Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, restSsl = Enabled.Yes(RestSsl.Ror(SourceFile.EsFile)), internodeSsl = Enabled.Yes(InternodeSsl.Ror(SourceFile.EsFile)) )) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala index 849da3ae98..56ca3dbda9 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackApiWithRorWithEnabledXpackSecuritySuite.scala @@ -25,11 +25,11 @@ import tech.beshu.ror.utils.misc.Version class XpackApiWithRorWithEnabledXpackSecuritySuite extends BaseXpackApiSuite { - override implicit val rorConfigFileName: String = "/xpack_api/readonlyrest_without_ror_ssl.yml" + override implicit val rorSettingsFileName: String = "/xpack_api/readonlyrest_without_ror_ssl.yml" override protected def rorClusterSecurityType: SecurityType = SecurityType.RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, restSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.RestSsl.Xpack), internodeSsl = Enabled.Yes(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.InternodeSsl.Xpack) )) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslKeystoreSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslKeystoreSuite.scala index eaf018f394..b0f9430b1f 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslKeystoreSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslKeystoreSuite.scala @@ -23,5 +23,5 @@ class XpackClusterWithRorNodesAndInternodeSslKeystoreSuite extends XpackClusterWithRorNodesAndInternodeSslSuite with PluginTestSupport { - override implicit val rorConfigFileName: String = "/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_keystore.yml" + override implicit val rorSettingsFileName: String = "/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_keystore.yml" } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslPemSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslPemSuite.scala index 82c6d58f5f..fa2bb23ea0 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslPemSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/XpackClusterWithRorNodesAndInternodeSslPemSuite.scala @@ -23,5 +23,5 @@ class XpackClusterWithRorNodesAndInternodeSslPemSuite extends XpackClusterWithRorNodesAndInternodeSslSuite with PluginTestSupport { - override implicit val rorConfigFileName: String = "/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_pem.yml" + override implicit val rorSettingsFileName: String = "/xpack_cluster_with_ror_nodes_and_internode_ssl/readonlyrest_pem.yml" } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/DisabledAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/DisabledAuditingToolsSuite.scala index ad31e913de..8b28a627b5 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/DisabledAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/DisabledAuditingToolsSuite.scala @@ -31,7 +31,7 @@ class DisabledAuditingToolsSuite with BeforeAndAfterEach with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/ror_audit/disabled_auditing_tools/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/ror_audit/disabled_auditing_tools/readonlyrest.yml" override val nodeDataInitializer = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala index f8553d61ef..6a9b03baa0 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala @@ -36,7 +36,7 @@ class LocalClusterAuditingToolsSuite private val isDataStreamSupported = Version.greaterOrEqualThan(esVersionUsed, 7, 9, 0) - override implicit val rorConfigFileName: String = { + override implicit val rorSettingsFileName: String = { if (isDataStreamSupported) { "/ror_audit/enabled_auditing_tools/readonlyrest.yml" } else { @@ -48,7 +48,7 @@ class LocalClusterAuditingToolsSuite override lazy val destNodesClientProviders: NonEmptyList[ClientProvider] = NonEmptyList.of(this) - override def baseRorConfig: String = resolvedRorConfigFile.contentAsString + override def baseRorConfig: String = resolvedRorSettingsFile.contentAsString override protected def baseAuditDataStreamName: Option[String] = Option.when(Version.greaterOrEqualThan(esVersionUsed, 7, 9, 0))("audit_data_stream") @@ -278,7 +278,7 @@ class LocalClusterAuditingToolsSuite updateRorConfig(Map(originalString -> newString)) private def updateRorConfig(replacements: Map[String, String]): Unit = { - val initialConfig = getResourceContent(rorConfigFileName) + val initialConfig = getResourceContent(rorSettingsFileName) val modifiedConfig = replacements.foldLeft(initialConfig) { case (soFar, (originalString, newString)) => soFar.replace(originalString, newString) } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/QueryAuditLogSerializerSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/QueryAuditLogSerializerSuite.scala index 14716ca28b..dcd3a102f8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/QueryAuditLogSerializerSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/QueryAuditLogSerializerSuite.scala @@ -35,7 +35,7 @@ class QueryAuditLogSerializerSuite with BeforeAndAfterEach with CustomScalaTestMatchers { - override implicit val rorConfigFileName: String = "/ror_audit/query_audit_log_serializer/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/ror_audit/query_audit_log_serializer/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(ElasticsearchTweetsInitializer) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala index 92e5989c9b..0a653e2c0d 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala @@ -39,7 +39,7 @@ class RemoteClusterAuditingToolsSuite private val isDataStreamSupported = Version.greaterOrEqualThan(esVersionUsed, 7, 9, 0) - override implicit val rorConfigFileName: String = { + override implicit val rorSettingsFileName: String = { if (isDataStreamSupported) { "/ror_audit/cluster_auditing_tools/readonlyrest.yml" } else { @@ -89,7 +89,7 @@ class RemoteClusterAuditingToolsSuite override lazy val destNodesClientProviders: NonEmptyList[ClientProvider] = NonEmptyList.fromListUnsafe(auditEsContainers) - override protected def baseRorConfig: String = resolvedRorConfigFile.contentAsString + override protected def baseRorConfig: String = resolvedRorSettingsFile.contentAsString override protected def baseAuditDataStreamName: Option[String] = Option.when(isDataStreamSupported)("audit_data_stream") diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala index ba7635183b..31a9f1c468 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala @@ -53,7 +53,7 @@ trait XpackClusterWithRorNodesAndInternodeSslSuite nodeTypes = NonEmptyList.of( NodeType( securityType = RorSecurity(ReadonlyRestPlugin.Config.Attributes.default.copy( - rorConfigFileName = rorConfigFileName, + rorSettingsFileName = rorSettingsFileName, restSsl = Enabled.Yes(RestSsl.Ror(SourceFile.RorFile)), internodeSsl = Enabled.Yes(InternodeSsl.Ror(SourceFile.RorFile)) )), diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/support.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/support.scala index 1302096571..11d0478bdb 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/support.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/support.scala @@ -26,7 +26,7 @@ import tech.beshu.ror.utils.containers.{DependencyDef, EsClusterContainer, EsClu object support { trait BaseEsClusterIntegrationTest - extends RorConfigFileNameProvider + extends RorSettingsFileNameProvider with MultipleClientsSupport with TestSuiteWithClosedTaskAssertion with ForAllTestContainer { @@ -38,7 +38,7 @@ object support { } trait BaseEsRemoteClusterIntegrationTest - extends RorConfigFileNameProvider + extends RorSettingsFileNameProvider with MultipleClientsSupport with TestSuiteWithClosedTaskAssertion with ForAllTestContainer { @@ -50,7 +50,7 @@ object support { } trait BaseManyEsClustersIntegrationTest - extends RorConfigFileNameProvider + extends RorSettingsFileNameProvider with MultipleClientsSupport with TestSuiteWithClosedTaskAssertion with ForAllTestContainer { @@ -65,7 +65,7 @@ object support { } trait BaseSingleNodeEsClusterTest - extends RorConfigFileNameProvider + extends RorSettingsFileNameProvider with SingleClientSupport with TestSuiteWithClosedTaskAssertion with NodeInitializerProvider { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsEngineSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsEngineSuite.scala index a28672ec08..42aeabe519 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsEngineSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsEngineSuite.scala @@ -23,7 +23,7 @@ class FieldRuleEsEngineSuite extends FieldRuleEngineSuite with SingletonPluginTestSupport { - override implicit val rorConfigFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_es.yml" + override implicit val rorSettingsFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_es.yml" override protected def unmodifiableQueryAssertion(result: SearchManager#SearchResult): Unit = { result should have statusCode 403 diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsWithLuceneEngineSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsWithLuceneEngineSuite.scala index 62df74b3c6..77d861be7a 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsWithLuceneEngineSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleEsWithLuceneEngineSuite.scala @@ -23,7 +23,7 @@ class FieldRuleEsWithLuceneEngineSuite extends FieldRuleEngineSuite with SingletonPluginTestSupport { - override implicit val rorConfigFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_es_with_lucene.yml" + override implicit val rorSettingsFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_es_with_lucene.yml" override protected def unmodifiableQueryAssertion(result: SearchManager#SearchResult): Unit = { result should have statusCode 200 diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleLuceneEngineSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleLuceneEngineSuite.scala index 641159781d..c91acaec00 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleLuceneEngineSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/engine/FieldRuleLuceneEngineSuite.scala @@ -23,7 +23,7 @@ class FieldRuleLuceneEngineSuite extends FieldRuleEngineSuite with SingletonPluginTestSupport { - override implicit val rorConfigFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_lucene.yml" + override implicit val rorSettingsFileName: String = "/field_level_security_engine/readonlyrest_fls_engine_lucene.yml" override protected def unmodifiableQueryAssertion(result: SearchManager#SearchResult): Unit = { result should have statusCode 200 diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/querydsl/FieldRuleQueryDSLSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/querydsl/FieldRuleQueryDSLSuite.scala index 497dae3b95..a245f7831a 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/querydsl/FieldRuleQueryDSLSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/querydsl/FieldRuleQueryDSLSuite.scala @@ -30,7 +30,7 @@ trait FieldRuleQueryDSLSuite with ESVersionSupportForAnyWordSpecLike { this: EsClusterProvider => - override implicit val rorConfigFileName: String = "/field_level_security_query/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/field_level_security_query/readonlyrest.yml" override def nodeDataInitializer = Some(FieldRuleQueryDSLSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/sourcefiltering/FieldRuleSourceFilteringSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/sourcefiltering/FieldRuleSourceFilteringSuite.scala index 0c1128116e..47896d3250 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/sourcefiltering/FieldRuleSourceFilteringSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/fields/sourcefiltering/FieldRuleSourceFilteringSuite.scala @@ -37,7 +37,7 @@ trait FieldRuleSourceFilteringSuite protected type CALL_RESULT <: BaseManager#JsonResponse - override implicit val rorConfigFileName: String = "/field_level_security/readonlyrest.yml" + override implicit val rorSettingsFileName: String = "/field_level_security/readonlyrest.yml" override def nodeDataInitializer: Option[ElasticsearchNodeDataInitializer] = Some(FieldRuleSourceFilteringSuite.nodeDataInitializer()) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/utils/PluginTestSupport.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/utils/PluginTestSupport.scala index 3103ca1b17..add4ea989e 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/utils/PluginTestSupport.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/utils/PluginTestSupport.scala @@ -31,21 +31,21 @@ trait SingletonPluginTestSupport extends PluginTestSupport with EsClusterProvider with BeforeAndAfterAll - with ResolvedRorConfigFileProvider { + with ResolvedRorSettingsFileProvider { this: Suite with BaseSingleNodeEsClusterTest => override lazy val targetEs: EsContainer = SingletonEsContainerWithRorSecurity.singleton.nodes.head private var startedDependencies = StartedClusterDependencies(Nil) - override final def resolvedRorConfigFile: File = { - resolveConfig.toTry.get + override final def resolvedRorSettingsFile: File = { + resolveSettings.toTry.get } override protected def beforeAll(): Unit = { startedDependencies = DependencyRunner.startDependencies(clusterDependencies) SingletonEsContainerWithRorSecurity.cleanUpContainer() - SingletonEsContainerWithRorSecurity.updateConfig(resolvedRorConfigFile.contentAsString) + SingletonEsContainerWithRorSecurity.updateSettings(resolvedRorSettingsFile.contentAsString) nodeDataInitializer.foreach(SingletonEsContainerWithRorSecurity.initNode) super.beforeAll() } @@ -55,16 +55,16 @@ trait SingletonPluginTestSupport startedDependencies.values.foreach(started => started.container.stop()) } - private def resolveConfig: Either[Throwable, File] = { + private def resolveSettings: Either[Throwable, File] = { Either.cond( test = startedDependencies.values.size === clusterDependencies.size, - right = resolvedConfig(startedDependencies), - left = new IllegalStateException("Not all dependencies are started. Cannot read resolved config yet") + right = resolvedSettings(startedDependencies), + left = new IllegalStateException("Not all dependencies are started. Cannot read resolved settings yet") ) } - private def resolvedConfig(startedDependencies: StartedClusterDependencies) = { - val configFile = File.apply(getResourcePath(rorConfigFileName)) - RorConfigAdjuster.adjustUsingDependencies(configFile, startedDependencies) + private def resolvedSettings(startedDependencies: StartedClusterDependencies) = { + val settingsFile = File.apply(getResourcePath(rorSettingsFileName)) + RorSettingsAdjuster.adjustUsingDependencies(settingsFile, startedDependencies) } } \ No newline at end of file diff --git a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala index 69ce367810..f47e9e671d 100644 --- a/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala +++ b/ror-tools/src/test/scala/tech/beshu/ror/tools/utils/ExampleEsWithRorContainer.scala @@ -65,7 +65,7 @@ class ExampleEsWithRorContainer(implicit scheduler: Scheduler) extends EsContain val clusterName = s"ROR_${uniqueClusterId.getAndIncrement()}" val nodeName = s"${clusterName}_1" val attributes = ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorConfigReloading = Enabled.No, + rorSettingsReloading = Enabled.No, rorSettingsFileName = "/basic/readonlyrest.yml", ) createCustomES( @@ -92,7 +92,7 @@ class ExampleEsWithRorContainer(implicit scheduler: Scheduler) extends EsContain val pluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin not assembled, build the plugin or run the test from Gradle")) val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) - val adjustedRorConfig = RorConfigAdjuster.adjustUsingDependencies( + val adjustedRorConfig = RorSettingsAdjuster.adjustUsingDependencies( source = rawRorConfigFile.toScala, startedDependencies = startedClusterDependencies, ) @@ -109,7 +109,7 @@ class ExampleEsWithRorContainer(implicit scheduler: Scheduler) extends EsContain ), securityConfig = ReadonlyRestWithEnabledXpackSecurityPlugin.Config( rorPlugin = pluginFile.toScala, - rorConfig = adjustedRorConfig, + rorSettings = adjustedRorConfig, attributes = attributes, ), initializer = nodeDataInitializer, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsClusterContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsClusterContainer.scala index 5b538e55a0..2c689c5913 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsClusterContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsClusterContainer.scala @@ -70,8 +70,8 @@ class EsClusterContainer private[containers](val esClusterSettings: EsClusterSet .runSyncUnsafe() } - def resolvedRorConfig(config: String): String = { - RorConfigAdjuster.adjustUsingDependencies(config, aStartedDependencies) + def resolvedRorSettings(config: String): String = { + RorSettingsAdjuster.adjustUsingDependencies(config, aStartedDependencies) } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala index 1091a28c8e..34a69bca3d 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainerCreator.scala @@ -82,10 +82,10 @@ trait EsContainerCreator { additionalLogConsumer: Option[Consumer[OutputFrame]], awaitingReadyStrategy: AwaitingReadyStrategy) = { val rorPluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin file assembly failed")) - val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) + val rawRorSettingsFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) - val adjustedRorConfig = RorConfigAdjuster.adjustUsingDependencies( - source = rawRorConfigFile.toScala, + val adjustedRorSettings = RorSettingsAdjuster.adjustUsingDependencies( + source = rawRorSettingsFile.toScala, startedDependencies = startedClusterDependencies, ) @@ -101,7 +101,7 @@ trait EsContainerCreator { ), securityConfig = ReadonlyRestWithEnabledXpackSecurityPlugin.Config( rorPlugin = rorPluginFile.toScala, - rorConfig = adjustedRorConfig, + rorSettings = adjustedRorSettings, attributes = attributes ), initializer = nodeDataInitializer, @@ -121,10 +121,10 @@ trait EsContainerCreator { additionalLogConsumer: Option[Consumer[OutputFrame]], awaitingReadyStrategy: AwaitingReadyStrategy) = { val rorPluginFile: File = project.assemble.getOrElse(throw new ContainerCreationException("Plugin file assembly failed")) - val rawRorConfigFile = ContainerUtils.getResourceFile(attributes.rorConfigFileName) + val rawRorSettingsFile = ContainerUtils.getResourceFile(attributes.rorSettingsFileName) - val adjustedRorConfig = RorConfigAdjuster.adjustUsingDependencies( - source = rawRorConfigFile.toScala, + val adjustedRorSettings = RorSettingsAdjuster.adjustUsingDependencies( + source = rawRorSettingsFile.toScala, startedDependencies = startedClusterDependencies, ) @@ -140,7 +140,7 @@ trait EsContainerCreator { ), rorConfig = ReadonlyRestPlugin.Config( rorPlugin = rorPluginFile.toScala, - rorConfig = adjustedRorConfig, + rorSettings = adjustedRorSettings, attributes = attributes ), initializer = nodeDataInitializer, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorConfigAdjuster.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorSettingsAdjuster.scala similarity index 90% rename from tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorConfigAdjuster.scala rename to tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorSettingsAdjuster.scala index 6fa86ce9b7..ebee6784ed 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorConfigAdjuster.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/RorSettingsAdjuster.scala @@ -21,25 +21,25 @@ import tech.beshu.ror.utils.containers.ContainerOps.* import tech.beshu.ror.utils.misc.OsUtils import tech.beshu.ror.utils.misc.OsUtils.CurrentOs -object RorConfigAdjuster { +object RorSettingsAdjuster { private val hostPlaceholder = "HOST" private val portPlaceholder = "PORT" final case class Replacement(host: String, port: Int) - def adjustUsingDependencies(config: String, + def adjustUsingDependencies(settings: String, startedDependencies: StartedClusterDependencies): String = { startedDependencies.values - .foldLeft(config)(replacePlaceholder) + .foldLeft(settings)(replacePlaceholder) } def adjustUsingDependencies(source: File, startedDependencies: StartedClusterDependencies): File = { - val configWithResolvedDependencies = startedDependencies.values + val settingsWithResolvedDependencies = startedDependencies.values .foldLeft(source.contentAsString)(replacePlaceholder) - createTempFile.overwrite(configWithResolvedDependencies) + createTempFile.overwrite(settingsWithResolvedDependencies) } private def replacePlaceholder(fileContent: String, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala index 3c83412f68..35f6de70dc 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/SingletonEsContainerWithRorSecurity.scala @@ -53,9 +53,9 @@ object SingletonEsContainerWithRorSecurity logOnFailure(snapshotManager.deleteAllRepositories().force()) } - def updateConfig(rorConfig: String): Unit = { + def updateSettings(rorSettings: String): Unit = { rorApiManager - .updateRorInIndexSettings(rorConfig) + .updateRorInIndexSettings(rorSettings) .forceOKStatusOrSettingsAlreadyLoaded() } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestPlugin.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestPlugin.scala index 95998b4b92..8555e1c984 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestPlugin.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestPlugin.scala @@ -29,24 +29,24 @@ import scala.concurrent.duration.{DurationInt, FiniteDuration} import scala.language.postfixOps object ReadonlyRestPlugin { - final case class Config(rorConfig: File, + final case class Config(rorSettings: File, rorPlugin: File, attributes: Attributes) object Config { - final case class Attributes(rorConfigReloading: Enabled[FiniteDuration], - rorInIndexConfigLoadingDelay: FiniteDuration, + final case class Attributes(rorSettingsReloading: Enabled[FiniteDuration], + rorInIndexSettingsLoadingDelay: FiniteDuration, rorCustomSettingsIndex: Option[String], restSsl: Enabled[RestSsl], internodeSsl: Enabled[InternodeSsl], - rorConfigFileName: String) + rorSettingsFileName: String) object Attributes { val default: Attributes = Attributes( - rorConfigReloading = Enabled.No, - rorInIndexConfigLoadingDelay = 0 seconds, + rorSettingsReloading = Enabled.No, + rorInIndexSettingsLoadingDelay = 0 seconds, rorCustomSettingsIndex = None, restSsl = Enabled.Yes(RestSsl.Ror(SourceFile.EsFile)), internodeSsl = Enabled.No, - rorConfigFileName = "/basic/readonlyrest.yml" + rorSettingsFileName = "/basic/readonlyrest.yml" ) } @@ -77,7 +77,7 @@ class ReadonlyRestPlugin(esVersion: String, .copyFile(esConfig.esConfigDir / "elastic-certificates-cert.pem", fromResourceBy(name = "elastic-certificates-cert.pem")) .copyFile(esConfig.esConfigDir / "elastic-certificates-pkey.pem", fromResourceBy(name = "elastic-certificates-pkey.pem")) .updateFipsDependencies(esConfig) - .copyFile(esConfig.esConfigDir / "readonlyrest.yml", config.rorConfig) + .copyFile(esConfig.esConfigDir / "readonlyrest.yml", config.rorSettings) .installRorPlugin(esConfig) .when(performPatching, _.patchES(esConfig)) } @@ -85,7 +85,7 @@ class ReadonlyRestPlugin(esVersion: String, override def updateEsConfigBuilder(builder: EsConfigBuilder): EsConfigBuilder = { builder .add("xpack.security.enabled: false") - .configureRorConfigAutoReloading() + .configureRorSettingsAutoReloading() .configureRorCustomIndexSettings() .configureRestSsl() .configureTransportSsl() @@ -102,7 +102,7 @@ class ReadonlyRestPlugin(esVersion: String, s"-Dcom.unboundid.ldap.sdk.debug.enabled=${if (enabled) true else false}" private def rorReloadingInterval() = { - val interval = config.attributes.rorConfigReloading match { + val interval = config.attributes.rorSettingsReloading match { case Enabled.No => "0sec" case Enabled.Yes(interval: FiniteDuration) => s"${interval.toMillis.toInt}ms" } @@ -111,7 +111,7 @@ class ReadonlyRestPlugin(esVersion: String, private def addLoadingSettings() = { Seq( - s"-Dcom.readonlyrest.settings.loading.delay=${config.attributes.rorInIndexConfigLoadingDelay.toMillis}ms", + s"-Dcom.readonlyrest.settings.loading.delay=${config.attributes.rorInIndexSettingsLoadingDelay.toMillis}ms", s"-Dcom.readonlyrest.settings.loading.attempts.count=1", s"-Dcom.readonlyrest.settings.loading.attempts.interval=0sec" ) @@ -187,8 +187,8 @@ class ReadonlyRestPlugin(esVersion: String, private implicit class ConfigureRorConfigReloading(val builder: EsConfigBuilder) { - def configureRorConfigAutoReloading(): EsConfigBuilder = { - config.attributes.rorConfigReloading match { + def configureRorSettingsAutoReloading(): EsConfigBuilder = { + config.attributes.rorSettingsReloading match { case Enabled.Yes(_) => builder case Enabled.No => diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala index 5852853b5f..7ec30df43a 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/images/ReadonlyRestWithEnabledXpackSecurityPlugin.scala @@ -26,20 +26,20 @@ import tech.beshu.ror.utils.containers.images.domain.Enabled import scala.concurrent.duration.FiniteDuration object ReadonlyRestWithEnabledXpackSecurityPlugin { - final case class Config(rorConfig: File, + final case class Config(rorSettings: File, rorPlugin: File, attributes: Attributes) object Config { - final case class Attributes(rorConfigReloading: Enabled[FiniteDuration], - rorInIndexConfigLoadingDelay: FiniteDuration, + final case class Attributes(rorSettingsReloading: Enabled[FiniteDuration], + rorInIndexSettingsLoadingDelay: FiniteDuration, rorCustomSettingsIndex: Option[String], restSsl: Enabled[RestSsl], internodeSsl: Enabled[InternodeSsl], rorSettingsFileName: String) object Attributes { val default: Attributes = Attributes( - rorConfigReloading = ReadonlyRestPlugin.Config.Attributes.default.rorConfigReloading, - rorInIndexConfigLoadingDelay = ReadonlyRestPlugin.Config.Attributes.default.rorInIndexConfigLoadingDelay, + rorSettingsReloading = ReadonlyRestPlugin.Config.Attributes.default.rorSettingsReloading, + rorInIndexSettingsLoadingDelay = ReadonlyRestPlugin.Config.Attributes.default.rorInIndexSettingsLoadingDelay, rorCustomSettingsIndex = ReadonlyRestPlugin.Config.Attributes.default.rorCustomSettingsIndex, restSsl = if(XpackSecurityPlugin.Config.Attributes.default.restSslEnabled) Enabled.Yes(RestSsl.Xpack) else Enabled.No, internodeSsl = if(XpackSecurityPlugin.Config.Attributes.default.internodeSslEnabled) Enabled.Yes(InternodeSsl.Xpack) else Enabled.No, @@ -93,11 +93,11 @@ class ReadonlyRestWithEnabledXpackSecurityPlugin(esVersion: String, private def createRorConfig() = { ReadonlyRestPlugin.Config( - rorConfig = config.rorConfig, + rorSettings = config.rorSettings, rorPlugin = config.rorPlugin, attributes = ReadonlyRestPlugin.Config.Attributes( - config.attributes.rorConfigReloading, - config.attributes.rorInIndexConfigLoadingDelay, + config.attributes.rorSettingsReloading, + config.attributes.rorInIndexSettingsLoadingDelay, config.attributes.rorCustomSettingsIndex, restSsl = createRorRestSsl(), internodeSsl = createRorInternodeSsl(), diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/providers.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/providers.scala index 3d4dad13e3..ba39588c20 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/providers.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/providers.scala @@ -48,12 +48,12 @@ object providers { private[providers] def client(credentials: Credentials): RestClient } - trait RorConfigFileNameProvider { - implicit def rorConfigFileName: String + trait RorSettingsFileNameProvider { + implicit def rorSettingsFileName: String } - trait ResolvedRorConfigFileProvider { - def resolvedRorConfigFile: File + trait ResolvedRorSettingsFileProvider { + def resolvedRorSettingsFile: File } trait NodeInitializerProvider { From 095c54e91ef2637d422ea75335bfeec6f6314f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 10:39:16 +0100 Subject: [PATCH 066/103] temp --- ...donlyrest.plugin-common-conventions.gradle | 8 +-- .../ror/boot/RorSettingsAutoReloader.scala | 6 +-- development.md | 2 +- .../suites/AdminApiAuthMockSuite.scala | 50 +++++++++---------- ror-tools/build.gradle | 3 ++ .../log4j2_es_7.10_and_newer.properties | 2 +- .../ror/utils/containers/EsContainer.scala | 9 ++++ .../ror/utils/elasticsearch/BaseManager.scala | 7 +++ 8 files changed, 52 insertions(+), 35 deletions(-) diff --git a/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle b/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle index fe2f2649dd..a048f1b764 100644 --- a/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle +++ b/build-base/src/main/groovy/readonlyrest.plugin-common-conventions.gradle @@ -82,10 +82,9 @@ tasks.withType(ScalaCompile).configureEach { ] } -tasks.withType(AbstractArchiveTask).configureEach { t -> - t.doLast { - def f = t.archiveFile.get().asFile - ant.checksum(file: f, algorithm: 'SHA-1', fileext: '.sha1') +tasks.withType(Zip).configureEach { task -> + task.doLast { + ant.checksum file: task.archiveFile.get().asFile, algorithm: 'sha1' } } @@ -103,6 +102,7 @@ tasks.register('generateVersionsFile') { tasks.register('toJar', Jar) { dependsOn generateVersionsFile duplicatesStrategy = DuplicatesStrategy.EXCLUDE + archiveBaseName = pluginName from sourceSets.main.getOutput() } diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala index 3bdef92e9d..3ab3e8df80 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala @@ -85,16 +85,16 @@ class EnabledRorSettingsAutoReloader(reloadInterval: PositiveFiniteDuration, private def scheduleIndexSettingsChecking(interval: PositiveFiniteDuration, reloadTask: RequestId => Task[Seq[(SettingsType, Either[ScheduledReloadError, Unit])]]) (implicit requestId: RequestId): CancelableWithRequestId = { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Scheduling next in-index settings check within ${interval.show}") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Scheduling next in-index settings check within ${interval.show}") val cancellable = scheduler.scheduleOnce(interval.value) { - logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Loading ReadonlyREST settings from index ...") + logger.debug(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Loading ReadonlyREST settings from index ...") reloadTask(requestId) .runAsync { case Right(reloadResults) => reloadResults.foreach(logSettingsReloadResult) scheduleNextIfNotStopping(interval, reloadTask) case Left(ex) => - logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}][${instance.id}] Checking index settings failed: error", ex) + logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) scheduleNextIfNotStopping(interval, reloadTask) } } diff --git a/development.md b/development.md index de57f3c1f7..38987ecdac 100644 --- a/development.md +++ b/development.md @@ -46,7 +46,7 @@ Currently eshome support debugging only es8x modules. * ROR plugin binaries can be found in `es70x/build/distributions/` **⚠️Required tools:** -* OpenJDK 21 +* Java 17 * Gradle ### Using Docker diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index ec457fb53f..15b7266913 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -24,12 +24,12 @@ import tech.beshu.ror.integration.suites.base.support.BaseManyEsClustersIntegrat import tech.beshu.ror.integration.utils.{ESVersionSupportForAnyWordSpecLike, PluginTestSupport, SingletonLdapContainers} import ujson.Value.Value import tech.beshu.ror.utils.TestUjson.ujson -import tech.beshu.ror.utils.containers.SecurityType.RorWithXpackSecurity import tech.beshu.ror.utils.containers.* import tech.beshu.ror.utils.containers.EsClusterSettings.positiveInt +import tech.beshu.ror.utils.containers.SecurityType.RorWithXpackSecurity import tech.beshu.ror.utils.containers.dependencies.{ldap, wiremock} -import tech.beshu.ror.utils.containers.images.domain.Enabled import tech.beshu.ror.utils.containers.images.ReadonlyRestWithEnabledXpackSecurityPlugin +import tech.beshu.ror.utils.containers.images.domain.Enabled import tech.beshu.ror.utils.elasticsearch.{DocumentManager, IndexManager, RorApiManager, SearchManager} import tech.beshu.ror.utils.misc.CustomScalaTestMatchers import tech.beshu.ror.utils.misc.Resources.getResourceContent @@ -55,12 +55,14 @@ class AdminApiAuthMockSuite override implicit val rorSettingsFileName: String = "/admin_api_mocks/readonlyrest.yml" private val readonlyrestIndexName = ".readonlyrest" + private val testSettingsEsDocumentId = "2" + private val settingsReloadInterval = 2 seconds private val esCluster: EsClusterContainer = { def esClusterSettingsCreator(securityType: SecurityType) = EsClusterSettings.create( clusterName = "ROR1", - numberOfInstances = positiveInt(2), + numberOfInstances = positiveInt(3), securityType = securityType, nodeDataInitializer = NoOpElasticsearchNodeDataInitializer, dependentServicesContainers = clusterDependencies @@ -69,7 +71,7 @@ class AdminApiAuthMockSuite createLocalClusterContainer( esClusterSettingsCreator( RorWithXpackSecurity(ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsReloading = Enabled.Yes(2 seconds), + rorSettingsReloading = Enabled.Yes(settingsReloadInterval), rorCustomSettingsIndex = Some(readonlyrestIndexName), rorSettingsFileName = rorSettingsFileName )) @@ -84,16 +86,13 @@ class AdminApiAuthMockSuite wiremock(name = "EXT1", portWhenRunningOnWindows = 8081, mappings = "/impersonation/wiremock_service2_ext_user_2.json", "/impersonation/wiremock_group_provider2_gpa_user_2.json"), ) - private val testEngineReloadInterval = 2 seconds - private val testSettingsEsDocumentId = "2" - "An admin Auth Mock REST API" should { "return info that test settings are not configured" when { "get current mocks" in { rorClients.foreach { rorApiManager => val response = rorApiManager.currentMockedServices() response should have statusCode 200 - response.responseJson should be (testSettingsNotConfiguredJson) + response.responseJson should be(testSettingsNotConfiguredJson) } } "update mocks" in { @@ -112,7 +111,7 @@ class AdminApiAuthMockSuite rorClients.foreach { rorApiManager => val response = rorApiManager.configureImpersonationMocks(updateMocksPayload(payloadServices)) response should have statusCode 200 - response.responseJson should be (testSettingsNotConfiguredJson) + response.responseJson should be(testSettingsNotConfiguredJson) } } } @@ -1234,6 +1233,14 @@ class AdminApiAuthMockSuite } } + override protected def beforeEach(): Unit = { + rorClients.foreach { + _.invalidateImpersonationMocks().force() + } + + removeRorIndexAndAwaitForNotSetTestConfig() + } + private def invalidateTestSettingsOnAllNodes(): Unit = { rorClients.head .invalidateRorTestSettings() @@ -1252,7 +1259,7 @@ class AdminApiAuthMockSuite response should have statusCode 200 val status = response.responseJson("status").str - expectedStatuses should contain (status) + expectedStatuses should contain(status) } private def updateMocksPayload(payloadServices: Value) = { @@ -1266,27 +1273,18 @@ class AdminApiAuthMockSuite ) } - private def testEngineSettings(): String = esCluster.resolvedRorSettings(getResourceContent(rorSettingsFileName)) + private def testSettingsFromFile(): String = esCluster.resolvedRorSettings(getResourceContent(rorSettingsFileName)) override implicit val patienceConfig: PatienceConfig = - PatienceConfig(timeout = testEngineReloadInterval.plus(10 second), interval = 500 millis) - - override protected def beforeEach(): Unit = { - rorClients.foreach { - _ - .invalidateImpersonationMocks() - .force() - } - - removeRorIndexAndAwaitForNotSetTestConfig() - } + PatienceConfig(timeout = settingsReloadInterval.plus(10 second), interval = 500 millis) private def removeRorIndexAndAwaitForNotSetTestConfig(): Unit = { // remove index storing test settings new IndexManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) .removeIndex(readonlyrestIndexName) + .successOrNotFound() - eventually { // await until node invalidate the test settings + eventually { // wait until node invalidate the test settings rorClients.foreach { assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_NOT_CONFIGURED", otherExpectedStatuses = "TEST_SETTINGS_INVALIDATED") } @@ -1294,7 +1292,7 @@ class AdminApiAuthMockSuite } private def setupTestSettingsInIndex(mocksJson: Value) = { - val testSettings = testEngineSettings() + val testSettings = testSettingsFromFile() val expirationTtl = 30 minutes val expirationTime = Instant.now().plus(expirationTtl.toMillis, ChronoUnit.MILLIS) val testSettingsJson = ujson.read( @@ -1331,7 +1329,7 @@ class AdminApiAuthMockSuite private def setupTestSettingsOnAllNodes(): Unit = { rorClients.head - .updateRorTestSettings(testEngineSettings()) + .updateRorTestSettings(testSettingsFromFile()) .forceOkStatus() eventually { // await until all nodes load settings @@ -1341,7 +1339,7 @@ class AdminApiAuthMockSuite } } - private def rorClients: List[RorApiManager] = { + private lazy val rorClients: List[RorApiManager] = { clients .toList .map(_.adminClient) diff --git a/ror-tools/build.gradle b/ror-tools/build.gradle index 84b5163e50..93fe88c89a 100644 --- a/ror-tools/build.gradle +++ b/ror-tools/build.gradle @@ -43,6 +43,9 @@ sourceSets { } test { + // Run tests with Java 17+ (required by Gradle Tooling API used in tests) + javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(17) } + systemProperty "project.dir", rootProject.projectDir enabled = project.hasProperty('esModule') if (enabled) { diff --git a/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties b/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties index 2fa3a9662c..3dcb296a30 100644 --- a/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties +++ b/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties @@ -84,5 +84,5 @@ logger.index_indexing_slowlog.additivity=false appender.header_warning.type = HeaderWarningAppender appender.header_warning.name = header_warning -logger.ror_ldap.name=tech.beshu.ror.accesscontrol.blocks.definitions.ldap.implementations +logger.ror_ldap.name=tech.beshu.ror logger.ror_ldap.level=debug \ No newline at end of file diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala index c534911217..4987ba5455 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala @@ -123,6 +123,15 @@ abstract class EsContainer(val esVersion: String, case None => new RestClient(sslEnabled, ip, port, Option.empty) } + override def start(): Unit = { + try { + super.start() + } catch { + case ex: Throwable => + logger.error("Container starting error", ex) + throw ex + } + } } object EsContainer { diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala index 7abf341db3..7c2c4ee21b 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala @@ -93,6 +93,13 @@ abstract class BaseManager(client: RestClient, this } + def successOrNotFound(): this.type = { + if (!(isSuccess || isNotFound)) throw new IllegalStateException( + s"Expected success or not found but got HTTP $responseCode, body: $body" + ) + this + } + override def toString: String = response.toString private def checkResponseAssertions(): Unit = { From 10e5107d272f5b6bce726f3a5e6a56da702b386a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 14:39:16 +0100 Subject: [PATCH 067/103] fix --- ror-tools/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ror-tools/build.gradle b/ror-tools/build.gradle index 93fe88c89a..e6e609012f 100644 --- a/ror-tools/build.gradle +++ b/ror-tools/build.gradle @@ -43,8 +43,8 @@ sourceSets { } test { - // Run tests with Java 17+ (required by Gradle Tooling API used in tests) - javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(17) } + // Run tests with Java 21 (required by Gradle Tooling API used in tests, matches CI environment) + javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(21) } systemProperty "project.dir", rootProject.projectDir enabled = project.hasProperty('esModule') From 4d3898ce9e48e74a1d42aba2b45643a486b8a07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 14:54:13 +0100 Subject: [PATCH 068/103] wip --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 3bcbd03af8..a760511a60 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { includeBuild('build-base') } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' } assert JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17) : From 05005d4574c0f8e1a67741e022cac9287312f341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 14:54:31 +0100 Subject: [PATCH 069/103] wip --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index a760511a60..3bcbd03af8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,7 +19,7 @@ pluginManagement { includeBuild('build-base') } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } assert JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17) : From c5449334995c70168675cfda091731a27eff2d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 15:43:12 +0100 Subject: [PATCH 070/103] improvements --- azure-pipelines.yml | 184 ++++++++++++++++++++++++++++++++++++++++---- ci/run-pipeline.sh | 122 +++++++++++++---------------- 2 files changed, 224 insertions(+), 82 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2245cdd636..8a1763a832 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,6 +7,7 @@ variables: isNewEsBranchOrPr: $[or(contains(variables['Build.SourceBranch'], 'newes/'), contains(variables['System.PullRequest.SourceBranch'], 'newes/'))] dependencyCheckCacheKey: $[format('dependency-check-v1-{0:yyyyMM}', pipeline.startTime)] dependencyCheckDataDir: '$(Pipeline.Workspace)/dependency-check-data/v1' + GRADLE_USER_HOME: '$(Pipeline.Workspace)/.gradle' trigger: batch: false @@ -64,10 +65,50 @@ stages: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + - stage: GRADLE_WARMUP + displayName: 'Warm up Gradle cache' + dependsOn: [ ] + condition: + and( + succeeded(), + or( + ne(variables['Build.Reason'], 'Manual'), + and(eq(variables['Build.Reason'], 'Manual'), startsWith('${{ parameters.actionToPerform }}', 'run_all_tests')) + ) + ) + jobs: + - job: WARMUP + displayName: 'Download Gradle and toolchains' + container: openjdk:22-jdk-slim + timeoutInMinutes: 30 + steps: + - checkout: self + fetchDepth: 1 + clean: false + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT + - bash: | + set +e + apt-get update && apt-get install -y git curl + echo "Warming up Gradle and toolchains..." + ./gradlew --no-daemon -q help + exit 0 + displayName: 'Download Gradle and toolchains (best effort)' + condition: ne(variables.GRADLE_CACHE_HIT, 'true') + env: + GRADLE_USER_HOME: $(GRADLE_USER_HOME) + - stage: OPTIONAL_CHECKS displayName: 'Optional checks' - dependsOn: [ ES_S3_UP ] - condition: and(in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), ne(variables['Build.Reason'], 'Manual')) + dependsOn: [ ES_S3_UP, GRADLE_WARMUP ] + condition: and(in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), in(dependencies.GRADLE_WARMUP.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), ne(variables['Build.Reason'], 'Manual')) jobs: - job: CVE_CHECK steps: @@ -75,6 +116,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - task: Cache@2 displayName: 'Restore CVE DB from cache' inputs: @@ -105,6 +155,7 @@ stages: var_is_fork: $(System.PullRequest.IsFork) var_oss_index_username: $(OSS_INDEX_USERNAME) var_oss_index_password: $(OSS_INDEX_PASSWORD) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: Cache@2 displayName: 'Save updated CVE DB in cache' inputs: @@ -115,8 +166,13 @@ stages: - stage: REQUIRED_CHECKS displayName: 'Required checks' - dependsOn: [ ES_S3_UP ] - condition: and(in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), ne(variables['Build.Reason'], 'Manual')) + dependsOn: [ ES_S3_UP, GRADLE_WARMUP ] + condition: + and( + in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), + in(dependencies.GRADLE_WARMUP.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), + ne(variables['Build.Reason'], 'Manual') + ) jobs: - job: steps: @@ -124,9 +180,20 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | echo "[REQUIRED_CHECKS] executing ROR_TASK = $ROR_TASK" ci/run-pipeline.sh + env: + GRADLE_USER_HOME: $(GRADLE_USER_HOME) strategy: maxParallel: 99 matrix: @@ -139,10 +206,11 @@ stages: - stage: TEST displayName: 'Run all tests' - dependsOn: [ ES_S3_UP ] + dependsOn: [ ES_S3_UP, GRADLE_WARMUP ] condition: and( in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), + in(dependencies.GRADLE_WARMUP.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), or( ne(variables['Build.Reason'], 'Manual'), and(eq(variables['Build.Reason'], 'Manual'), startsWith('${{ parameters.actionToPerform }}', 'run_all_tests')) @@ -165,6 +233,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -176,6 +253,7 @@ stages: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) ROR_TASK: core_tests + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -186,7 +264,8 @@ stages: ####################################################### ##### Integration tests for ES 9.x on master/develop ####################################################### - - job: + - job: IT_ES9x_MAIN + displayName: 'Integration tests ES 9.x (master/develop)' condition: and( succeeded(), @@ -204,6 +283,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -214,6 +302,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -233,7 +322,8 @@ stages: ####################################################### ##### Integration tests for ES 8.x on master/develop ####################################################### - - job: + - job: IT_ES8x_MAIN + displayName: 'Integration tests ES 8.x (master/develop)' condition: and( succeeded(), @@ -251,6 +341,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -261,6 +360,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -374,7 +474,8 @@ stages: ####################################################### ##### Integration tests for ES 9.x on PRs ####################################################### - - job: + - job: IT_ES9x_PR + displayName: 'Integration tests ES 9.x (PRs)' condition: and( succeeded(), @@ -390,6 +491,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -400,6 +510,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -417,7 +528,8 @@ stages: ####################################################### ##### Integration tests for ES 8.x on PRs ####################################################### - - job: + - job: IT_ES8x_PR + displayName: 'Integration tests ES 8.x (PRs)' condition: and( succeeded(), @@ -433,6 +545,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -443,6 +564,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -783,7 +905,15 @@ stages: - checkout: self fetchDepth: 1 clean: false - + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | set -e @@ -796,6 +926,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) strategy: maxParallel: 99 @@ -855,7 +986,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true - + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | set -e @@ -869,6 +1008,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) strategy: maxParallel: 99 @@ -906,7 +1046,15 @@ stages: clean: false persistCredentials: true timeoutInMinutes: 180 - + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | set -e @@ -931,6 +1079,7 @@ stages: var_aws_secret_access_key: $(aws_secret_access_key) var_docker_registry_user: $(DOCKER_REGISTRY_USER) var_docker_registry_password: $(DOCKER_REGISTRY_PASSWORD) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) strategy: maxParallel: 99 @@ -966,7 +1115,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true - + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT # Populate the global variable mvn_status for later - script: | PLUGIN_VER=$(awk -F= '$1=="pluginVersion" {print $2}' gradle.properties) @@ -1013,6 +1170,7 @@ stages: VAR_MAVEN_STAGING_PROFILE_ID: $(MAVEN_STAGING_PROFILE_ID) VAR_GPG_PASSPHRASE: $(GPG_PASSPHRASE) VAR_GPG_KEY_ID: $(GPG_KEY_ID) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) condition: eq(404, variables.mvn_status) - stage: PRE_BUILDS_DOCKER_IMAGE_PUBLISHING diff --git a/ci/run-pipeline.sh b/ci/run-pipeline.sh index eda0cc3b6a..5bb9174547 100755 --- a/ci/run-pipeline.sh +++ b/ci/run-pipeline.sh @@ -4,43 +4,32 @@ source "$(dirname "$0")/ci-lib.sh" trap 'echo "Termination signal received. Exiting..."; exit 1' SIGTERM SIGINT -echo ">>> ($0) RUNNING CONTINUOUS INTEGRATION" - -export TRAVIS_BRANCH=$(git symbolic-ref --short -q HEAD) - -if [ "$BUILD_SOURCEBRANCHNAME" ]; then - export TRAVIS=true - export TRAVIS_BRANCH=$BUILD_SOURCEBRANCHNAME -fi -echo ">> FOUND BUILD PARAMETERS: task? $ROR_TASK; is CI? $TRAVIS; branch? $TRAVIS_BRANCH" +echo ">>> ($0) RUNNING CONTINUOUS INTEGRATION; task? $ROR_TASK" # Log file friendly Gradle output export TERM=dumb -# Adaptation for Azure -([ ! -z $BUILD_BUILDNUMBER ] || [ "$TRAVIS" ]) && TRAVIS="true" - -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "license_check" ]]; then +if [[ $ROR_TASK == "license_check" ]]; then echo ">>> Check all license headers are in place" ./gradlew --no-daemon license fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "cve_check" ]]; then +if [[ $ROR_TASK == "cve_check" ]]; then echo ">>> Running CVE checks.." ./gradlew --no-daemon dependencyCheckAnalyze fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "compile_codebase_check" ]]; then +if [[ $ROR_TASK == "compile_codebase_check" ]]; then echo ">>> Running compile codebase.." ./gradlew --no-daemon classes fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "audit_build_check" ]]; then +if [[ $ROR_TASK == "audit_build_check" ]]; then echo ">>> Running audit module cross build.." ./gradlew --no-daemon --stacktrace audit:crossBuildAssemble fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "core_tests" ]]; then +if [[ $ROR_TASK == "core_tests" ]]; then echo ">>> Running unit tests.." ./gradlew --no-daemon --stacktrace core:test audit:test fi @@ -57,143 +46,138 @@ run_integration_tests() { ./gradlew --no-daemon ror-tools:test integration-tests:test "-PesModule=$ES_MODULE" || (find . | grep hs_err | xargs cat && exit 1) } -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es92x" ]]; then +if [[ $ROR_TASK == "integration_es92x" ]]; then run_integration_tests "es92x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es91x" ]]; then +if [[ $ROR_TASK == "integration_es91x" ]]; then run_integration_tests "es91x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es90x" ]]; then +if [[ $ROR_TASK == "integration_es90x" ]]; then run_integration_tests "es90x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es818x" ]]; then +if [[ $ROR_TASK == "integration_es818x" ]]; then run_integration_tests "es818x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es816x" ]]; then +if [[ $ROR_TASK == "integration_es816x" ]]; then run_integration_tests "es816x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es815x" ]]; then +if [[ $ROR_TASK == "integration_es815x" ]]; then run_integration_tests "es815x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es814x" ]]; then +if [[ $ROR_TASK == "integration_es814x" ]]; then run_integration_tests "es814x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es813x" ]]; then +if [[ $ROR_TASK == "integration_es813x" ]]; then run_integration_tests "es813x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es812x" ]]; then +if [[ $ROR_TASK == "integration_es812x" ]]; then run_integration_tests "es812x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es811x" ]]; then +if [[ $ROR_TASK == "integration_es811x" ]]; then run_integration_tests "es811x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es810x" ]]; then +if [[ $ROR_TASK == "integration_es810x" ]]; then run_integration_tests "es810x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es89x" ]]; then +if [[ $ROR_TASK == "integration_es89x" ]]; then run_integration_tests "es89x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es88x" ]]; then +if [[ $ROR_TASK == "integration_es88x" ]]; then run_integration_tests "es88x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es87x" ]]; then +if [[ $ROR_TASK == "integration_es87x" ]]; then run_integration_tests "es87x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es85x" ]]; then +if [[ $ROR_TASK == "integration_es85x" ]]; then run_integration_tests "es85x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es84x" ]]; then +if [[ $ROR_TASK == "integration_es84x" ]]; then run_integration_tests "es84x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es83x" ]]; then +if [[ $ROR_TASK == "integration_es83x" ]]; then run_integration_tests "es83x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es82x" ]]; then +if [[ $ROR_TASK == "integration_es82x" ]]; then run_integration_tests "es82x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es81x" ]]; then +if [[ $ROR_TASK == "integration_es81x" ]]; then run_integration_tests "es81x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es80x" ]]; then +if [[ $ROR_TASK == "integration_es80x" ]]; then run_integration_tests "es80x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es717x" ]]; then +if [[ $ROR_TASK == "integration_es717x" ]]; then run_integration_tests "es717x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es716x" ]]; then +if [[ $ROR_TASK == "integration_es716x" ]]; then run_integration_tests "es716x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es714x" ]]; then +if [[ $ROR_TASK == "integration_es714x" ]]; then run_integration_tests "es714x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es711x" ]]; then +if [[ $ROR_TASK == "integration_es711x" ]]; then run_integration_tests "es711x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es710x" ]]; then +if [[ $ROR_TASK == "integration_es710x" ]]; then run_integration_tests "es710x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es79x" ]]; then +if [[ $ROR_TASK == "integration_es79x" ]]; then run_integration_tests "es79x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es78x" ]]; then +if [[ $ROR_TASK == "integration_es78x" ]]; then run_integration_tests "es78x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es77x" ]]; then +if [[ $ROR_TASK == "integration_es77x" ]]; then run_integration_tests "es77x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es74x" ]]; then +if [[ $ROR_TASK == "integration_es74x" ]]; then run_integration_tests "es74x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es73x" ]]; then +if [[ $ROR_TASK == "integration_es73x" ]]; then run_integration_tests "es73x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es72x" ]]; then +if [[ $ROR_TASK == "integration_es72x" ]]; then run_integration_tests "es72x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es70x" ]]; then +if [[ $ROR_TASK == "integration_es70x" ]]; then run_integration_tests "es70x" fi -if [[ -z $TRAVIS ]] || [[ $ROR_TASK == "integration_es67x" ]]; then +if [[ $ROR_TASK == "integration_es67x" ]]; then run_integration_tests "es67x" fi -if [[ $TRAVIS_PULL_REQUEST == "true" ]] && [[ $TRAVIS_BRANCH != "master" ]]; then - echo ">>> won't try to create builds because this is a PR" - exit 0 -fi - build_ror_plugins() { if [ "$#" -ne 1 ]; then echo "What ES versions should I build plugins for?" @@ -220,19 +204,19 @@ build_ror_plugin() { ./gradlew buildRorPlugin "-PesVersion=$ROR_VERSION" Date: Tue, 9 Dec 2025 16:10:09 +0100 Subject: [PATCH 071/103] improvements --- azure-pipelines.yml | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8a1763a832..c2bccb9cca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -264,8 +264,7 @@ stages: ####################################################### ##### Integration tests for ES 9.x on master/develop ####################################################### - - job: IT_ES9x_MAIN - displayName: 'Integration tests ES 9.x (master/develop)' + - job: condition: and( succeeded(), @@ -322,8 +321,7 @@ stages: ####################################################### ##### Integration tests for ES 8.x on master/develop ####################################################### - - job: IT_ES8x_MAIN - displayName: 'Integration tests ES 8.x (master/develop)' + - job: condition: and( succeeded(), @@ -425,6 +423,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -435,6 +442,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: @@ -474,8 +482,7 @@ stages: ####################################################### ##### Integration tests for ES 9.x on PRs ####################################################### - - job: IT_ES9x_PR - displayName: 'Integration tests ES 9.x (PRs)' + - job: condition: and( succeeded(), @@ -528,8 +535,7 @@ stages: ####################################################### ##### Integration tests for ES 8.x on PRs ####################################################### - - job: IT_ES8x_PR - displayName: 'Integration tests ES 8.x (PRs)' + - job: condition: and( succeeded(), @@ -601,6 +607,15 @@ stages: fetchDepth: 1 clean: false persistCredentials: true + - task: Cache@2 + displayName: 'Restore Gradle cache' + inputs: + key: 'gradle | "$(Agent.OS)" | **/gradle/wrapper/gradle-wrapper.properties | **/settings.gradle* | **/build.gradle* | **/gradle.properties' + restoreKeys: | + gradle | "$(Agent.OS)" + gradle + path: $(GRADLE_USER_HOME) + cacheHitVar: GRADLE_CACHE_HIT - script: | # Translate back env vars to avoid cyclical reference :/ export aws_access_key_id=$var_aws_access_key_id @@ -611,6 +626,7 @@ stages: env: var_aws_access_key_id: $(aws_access_key_id) var_aws_secret_access_key: $(aws_secret_access_key) + GRADLE_USER_HOME: $(GRADLE_USER_HOME) - task: PublishTestResults@2 condition: failed() inputs: From ba320862cd7bbbb3309ba331a369cab94cb1542b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 9 Dec 2025 16:24:20 +0100 Subject: [PATCH 072/103] improvements --- azure-pipelines.yml | 21 +++++++++++++++------ ror-tools/build.gradle | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c2bccb9cca..bc4a52afdf 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -79,7 +79,7 @@ stages: jobs: - job: WARMUP displayName: 'Download Gradle and toolchains' - container: openjdk:22-jdk-slim + container: eclipse-temurin:17-jdk timeoutInMinutes: 30 steps: - checkout: self @@ -111,6 +111,7 @@ stages: condition: and(in(dependencies.ES_S3_UP.result, 'Succeeded', 'Skipped'), in(dependencies.GRADLE_WARMUP.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), ne(variables['Build.Reason'], 'Manual')) jobs: - job: CVE_CHECK + container: eclipse-temurin:17-jdk steps: - checkout: self fetchDepth: 1 @@ -175,6 +176,7 @@ stages: ) jobs: - job: + container: eclipse-temurin:17-jdk steps: - checkout: self fetchDepth: 1 @@ -227,6 +229,7 @@ stages: not(and(eq(variables['Build.Reason'], 'Manual'), eq('${{ parameters.actionToPerform }}', 'run_all_tests_on_windows'))) ) displayName: 'Unit tests' + container: eclipse-temurin:17-jdk timeoutInMinutes: 30 steps: - checkout: self @@ -275,7 +278,7 @@ stages: and(eq(variables['Build.Reason'], 'Manual'), eq('${{ parameters.actionToPerform }}', 'run_all_tests_on_linux')) ) ) - container: openjdk:22-jdk-slim + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -332,7 +335,7 @@ stages: and(eq(variables['Build.Reason'], 'Manual'), eq('${{ parameters.actionToPerform }}', 'run_all_tests_on_linux')) ) ) - container: openjdk:22-jdk-slim + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -417,6 +420,7 @@ stages: and(eq(variables['Build.Reason'], 'Manual'), eq('${{ parameters.actionToPerform }}', 'run_all_tests_on_linux')) ) ) + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -491,7 +495,7 @@ stages: ne(variables.isMaster, true), not(and(eq(variables['Build.Reason'], 'Manual'), startsWith('${{ parameters.actionToPerform }}', 'run_all_tests'))) ) - container: openjdk:22-jdk-slim + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -544,7 +548,7 @@ stages: ne(variables.isMaster, true), not(and(eq(variables['Build.Reason'], 'Manual'), startsWith('${{ parameters.actionToPerform }}', 'run_all_tests'))) ) - container: openjdk:22-jdk-slim + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -601,6 +605,7 @@ stages: ne(variables.isMaster, true), not(and(eq(variables['Build.Reason'], 'Manual'), startsWith('${{ parameters.actionToPerform }}', 'run_all_tests'))) ) + container: eclipse-temurin:17-jdk timeoutInMinutes: 120 steps: - checkout: self @@ -916,6 +921,7 @@ stages: ) jobs: - job: + container: eclipse-temurin:17-jdk timeoutInMinutes: 180 steps: - checkout: self @@ -996,6 +1002,7 @@ stages: ) jobs: - job: + container: eclipse-temurin:17-jdk timeoutInMinutes: 600 steps: - checkout: self @@ -1055,6 +1062,7 @@ stages: ) jobs: - job: + container: eclipse-temurin:17-jdk timeoutInMinutes: 180 steps: - checkout: self @@ -1075,7 +1083,7 @@ stages: set -e echo ">>>> Installing dependencies with apt-get" - sudo apt-get update && sudo apt-get install -y git file + apt-get update && apt-get install -y git file git status && echo ">>> Git installed correctly!" # Translate back env vars to avoid cyclical reference :/ @@ -1126,6 +1134,7 @@ stages: ) jobs: - job: + container: eclipse-temurin:17-jdk steps: - checkout: self fetchDepth: 1 diff --git a/ror-tools/build.gradle b/ror-tools/build.gradle index e6e609012f..a8176d5907 100644 --- a/ror-tools/build.gradle +++ b/ror-tools/build.gradle @@ -44,7 +44,7 @@ sourceSets { test { // Run tests with Java 21 (required by Gradle Tooling API used in tests, matches CI environment) - javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(21) } + javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(17) } systemProperty "project.dir", rootProject.projectDir enabled = project.hasProperty('esModule') From 348eb493453145b5fa4ee5a026eeee5a218ac75c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Thu, 11 Dec 2025 07:57:45 +0100 Subject: [PATCH 073/103] wipt --- .../blocks/ImpersonationWarning.scala | 2 +- .../factory/HttpClientsFactory.scala | 30 +- .../TestSettingsBasedReloadableEngine.scala | 2 +- .../factory/ImpersonationWarningsTests.scala | 2 +- docs/api/ror-internal-api-swagger.yaml | 4 +- .../plugin-metadata/entitlement-policy.yaml | 10 + .../suites/AdminApiAuthMockSuite.scala | 46 +- .../AdminApiWithDefaultRorIndexSuite.scala | 4 +- .../suites/base/BaseAdminApiSuite.scala | 545 +++++++++--------- 9 files changed, 338 insertions(+), 307 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala index b3bacf1c5c..23c3d39cff 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala @@ -164,7 +164,7 @@ object ImpersonationWarning { Some(ImpersonationWarning( block = blockName, ruleName = rule.name, - message = nes("The rule contains fully hashed username and password. It doesn't support impersonation in this configuration"), + message = nes("The rule contains fully hashed username and password. It doesn't support impersonation in this use case.."), hint = s"You can use second version of the rule and use not hashed username. Like that: `${rule.name.show}: USER_NAME:hash(PASSWORD)" )) case _: HashedCredentials.HashedOnlyPassword => diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/HttpClientsFactory.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/HttpClientsFactory.scala index 1ac8e2218d..40c7f8104f 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/HttpClientsFactory.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/factory/HttpClientsFactory.scala @@ -81,7 +81,7 @@ object HttpClientsFactory { } // todo: remove synchronized, use more sophisticated lock mechanism -class AsyncHttpClientsFactory extends HttpClientsFactory { +class AsyncHttpClientsFactory extends HttpClientsFactory with Logging { private val existingClients = new CopyOnWriteArrayList[AsyncHttpClient]() private val isWorking = AtomicBoolean(true) @@ -102,17 +102,23 @@ class AsyncHttpClientsFactory extends HttpClientsFactory { } private def newAsyncHttpClient(config: Config) = { - val timer = new HashedWheelTimer - val maxIdleTimeout = 60.seconds - val connectionTtl = -1.milliseconds - val cleanerPeriod = -1.milliseconds - val pool = new DefaultChannelPool(maxIdleTimeout.toJava, connectionTtl.toJava, DefaultChannelPool.PoolLeaseStrategy.FIFO, timer, cleanerPeriod.toJava) - asyncHttpClient { - new DefaultAsyncHttpClientConfig.Builder() - .setNettyTimer(timer) - .setChannelPool(pool) - .setUseInsecureTrustManager(!config.validate) - .build() + try { + val timer = new HashedWheelTimer + val maxIdleTimeout = 60.seconds + val connectionTtl = -1.milliseconds + val cleanerPeriod = -1.milliseconds + val pool = new DefaultChannelPool(maxIdleTimeout.toJava, connectionTtl.toJava, DefaultChannelPool.PoolLeaseStrategy.FIFO, timer, cleanerPeriod.toJava) + asyncHttpClient { + new DefaultAsyncHttpClientConfig.Builder() + .setNettyTimer(timer) + .setChannelPool(pool) + .setUseInsecureTrustManager(!config.validate) + .build() + } + } catch { + case ex: Throwable => + logger.error("ERR: ", ex) + throw ex } } } diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 771dba6a52..9d1f53e73f 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -221,7 +221,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest EitherT(testSettingsSource.load()) .map(Some(_)) .leftFlatMap { - case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound) => + case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound | LoadingError.IndexNotFound) => EitherT.rightT(None) case error => EitherT.leftT(IndexSettingsReloadError.IndexLoadingSettingsError(error): IndexSettingsReloadError) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala index 817bb6ae9c..3505c25d3f 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/ImpersonationWarningsTests.scala @@ -356,7 +356,7 @@ class ImpersonationWarningsTests extends AnyWordSpec with Inside { warning( blockName, ruleName, - message = "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration", + message = "The rule contains fully hashed username and password. It doesn't support impersonation in this use case.", hint = s"You can use second version of the rule and use not hashed username. Like that: `$ruleName: USER_NAME:hash(PASSWORD)" ) } diff --git a/docs/api/ror-internal-api-swagger.yaml b/docs/api/ror-internal-api-swagger.yaml index bca4f10ded..3b237a1249 100644 --- a/docs/api/ror-internal-api-swagger.yaml +++ b/docs/api/ror-internal-api-swagger.yaml @@ -1508,7 +1508,7 @@ components: warnings: - block_name: other rule_name: auth_key_sha1 - message: "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration" + message: "The rule contains fully hashed username and password. It doesn't support impersonation in this use case." hint: "You can use second version of the rule and use not hashed username. Like that: `auth_key_sha1: USER_NAME:hash(PASSWORD)" TestSettingsNotConfiguredResponseExample: @@ -1543,7 +1543,7 @@ components: warnings: - block_name: other rule_name: auth_key_sha1 - message: "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration" + message: "The rule contains fully hashed username and password. It doesn't support impersonation in this use case." hint: "You can use second version of the rule and use not hashed username. Like that: `auth_key_sha1: USER_NAME:hash(PASSWORD)" TestSettingsUpdateFailedResponseExample: diff --git a/es818x/plugin-metadata/entitlement-policy.yaml b/es818x/plugin-metadata/entitlement-policy.yaml index e48762faa8..3f59d734d4 100644 --- a/es818x/plugin-metadata/entitlement-policy.yaml +++ b/es818x/plugin-metadata/entitlement-policy.yaml @@ -3,6 +3,16 @@ ALL-UNNAMED: - relative_path: ../ relative_to: config mode: read + - path: "/etc/os-release" + mode: "read" + - path: "/usr/lib/os-release" + mode: "read" + - path: "/proc/sys/net/core/somaxconn" + mode: read + - path: "/usr/share/elasticsearch/.aws/config" + mode: read + - path: "/usr/share/elasticsearch/.aws/credentials" + mode: read - manage_threads - inbound_network - outbound_network \ No newline at end of file diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index 15b7266913..900bcb3478 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -34,8 +34,8 @@ import tech.beshu.ror.utils.elasticsearch.{DocumentManager, IndexManager, RorApi import tech.beshu.ror.utils.misc.CustomScalaTestMatchers import tech.beshu.ror.utils.misc.Resources.getResourceContent -import java.time.{Instant, ZoneOffset} import java.time.temporal.ChronoUnit +import java.time.{Instant, ZoneOffset} import scala.concurrent.duration.* import scala.language.postfixOps @@ -62,7 +62,7 @@ class AdminApiAuthMockSuite def esClusterSettingsCreator(securityType: SecurityType) = EsClusterSettings.create( clusterName = "ROR1", - numberOfInstances = positiveInt(3), + numberOfInstances = positiveInt(2), securityType = securityType, nodeDataInitializer = NoOpElasticsearchNodeDataInitializer, dependentServicesContainers = clusterDependencies @@ -92,7 +92,7 @@ class AdminApiAuthMockSuite rorClients.foreach { rorApiManager => val response = rorApiManager.currentMockedServices() response should have statusCode 200 - response.responseJson should be(testSettingsNotConfiguredJson) + response.responseJson should be (testSettingsNotConfiguredJson) } } "update mocks" in { @@ -111,7 +111,7 @@ class AdminApiAuthMockSuite rorClients.foreach { rorApiManager => val response = rorApiManager.configureImpersonationMocks(updateMocksPayload(payloadServices)) response should have statusCode 200 - response.responseJson should be(testSettingsNotConfiguredJson) + response.responseJson should be (testSettingsNotConfiguredJson) } } } @@ -200,7 +200,7 @@ class AdminApiAuthMockSuite | { | "block_name": "test2 (1)", | "rule_name": "auth_key_sha1", - | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration", + | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this use case.", | "hint": "You can use second version of the rule and use not hashed username. Like that: `auth_key_sha1: USER_NAME:hash(PASSWORD)" | }, | { @@ -649,7 +649,7 @@ class AdminApiAuthMockSuite |""".stripMargin )) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => val response = rorApiManager.currentMockedServices() response should have statusCode 200 @@ -668,7 +668,7 @@ class AdminApiAuthMockSuite | { | "block_name": "test2 (1)", | "rule_name": "auth_key_sha1", - | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration", + | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this use case.", | "hint": "You can use second version of the rule and use not hashed username. Like that: `auth_key_sha1: USER_NAME:hash(PASSWORD)" | } |] @@ -676,11 +676,11 @@ class AdminApiAuthMockSuite )) } } - "return info that all mocks are configured when old config version stored in index" in { + "return info that all mocks are configured when old settings version stored in index" in { setupTestSettingsOnAllNodes() invalidateTestSettingsOnAllNodes() - setupTestSettingsInIndex( + setupTestSettingsInIndex(ujson.read( s""" |{ | "ldapMocks": { @@ -761,7 +761,7 @@ class AdminApiAuthMockSuite | } |} |""".stripMargin - ) + )) val payloadServices = ujson.read( s""" @@ -885,7 +885,7 @@ class AdminApiAuthMockSuite |""".stripMargin ) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => val response = rorApiManager.currentMockedServices() response should have statusCode 200 @@ -897,7 +897,7 @@ class AdminApiAuthMockSuite } "provide a method for reload mocked services" which { "is going to reload mocked services" when { - "configuration is correct" when { + "settings are correct" when { "all services are passed" in { setupTestSettingsOnAllNodes() @@ -1238,7 +1238,7 @@ class AdminApiAuthMockSuite _.invalidateImpersonationMocks().force() } - removeRorIndexAndAwaitForNotSetTestConfig() + removeRorIndexAndAwaitForNotSetTestSettings() } private def invalidateTestSettingsOnAllNodes(): Unit = { @@ -1246,20 +1246,17 @@ class AdminApiAuthMockSuite .invalidateRorTestSettings() .forceOkStatus() - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_INVALIDATED") } } } - private def assertCurrentTestSettings(rorApiManager: RorApiManager, expectedStatus: String, otherExpectedStatuses: String*) = { + private def assertCurrentTestSettings(rorApiManager: RorApiManager, expectedStatus: String) = { val response = rorApiManager.currentRorTestSettings - val expectedStatuses = expectedStatus :: otherExpectedStatuses.toList response should have statusCode 200 - - val status = response.responseJson("status").str - expectedStatuses should contain(status) + response.responseJson("status").str should be(expectedStatus) } private def updateMocksPayload(payloadServices: Value) = { @@ -1278,7 +1275,7 @@ class AdminApiAuthMockSuite override implicit val patienceConfig: PatienceConfig = PatienceConfig(timeout = settingsReloadInterval.plus(10 second), interval = 500 millis) - private def removeRorIndexAndAwaitForNotSetTestConfig(): Unit = { + private def removeRorIndexAndAwaitForNotSetTestSettings(): Unit = { // remove index storing test settings new IndexManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) .removeIndex(readonlyrestIndexName) @@ -1286,7 +1283,7 @@ class AdminApiAuthMockSuite eventually { // wait until node invalidate the test settings rorClients.foreach { - assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_NOT_CONFIGURED", otherExpectedStatuses = "TEST_SETTINGS_INVALIDATED") + assertCurrentTestSettings(_, expectedStatus = "TEST_SETTINGS_NOT_CONFIGURED") } } } @@ -1295,7 +1292,7 @@ class AdminApiAuthMockSuite val testSettings = testSettingsFromFile() val expirationTtl = 30 minutes val expirationTime = Instant.now().plus(expirationTtl.toMillis, ChronoUnit.MILLIS) - val testSettingsJson = ujson.read( + val testSettingsRelatedDocument = ujson.read( s""" |{ | "settings": ${ujson.write(testSettings)}, @@ -1307,8 +1304,9 @@ class AdminApiAuthMockSuite ) val documentType = "settings" val documentManager = new DocumentManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) - val createDocResponse = documentManager.createDoc(readonlyrestIndexName, documentType, testSettingsEsDocumentId, testSettingsJson) - createDocResponse.isSuccess should be(true) + val createDocResponse = documentManager.createDoc(readonlyrestIndexName, documentType, testSettingsEsDocumentId, testSettingsRelatedDocument) + + createDocResponse should have statusCode 200 } private def assertAuthMocksInIndex(expectedMocks: Value) = { diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala index d11c11c57d..66a38f68d3 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiWithDefaultRorIndexSuite.scala @@ -31,7 +31,7 @@ class AdminApiWithDefaultRorIndexSuite override implicit val rorSettingsFileName: String = "/admin_api/readonlyrest.yml" override protected val readonlyrestIndexName: String = ".readonlyrest" - override protected lazy val rorWithIndexConfig: EsClusterContainer = { + override protected lazy val rorWithIndexSettings: EsClusterContainer = { def esClusterSettingsCreator(securityType: SecurityType) = EsClusterSettings.create( clusterName = "ROR1", @@ -50,7 +50,7 @@ class AdminApiWithDefaultRorIndexSuite ) } - override protected lazy val rorWithNoIndexConfig: EsClusterContainer = { + override protected lazy val rorWithNoIndexSettings: EsClusterContainer = { def esClusterSettingsCreator(securityType: SecurityType) = EsClusterSettings.create( clusterName = "ROR2", diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala index 32ba76a027..83d7c93aeb 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala @@ -49,37 +49,37 @@ trait BaseAdminApiSuite protected def readonlyrestIndexName: String - protected def rorWithIndexConfig: EsClusterContainer + protected def rorWithIndexSettings: EsClusterContainer - protected def rorWithNoIndexConfig: EsClusterContainer + protected def rorWithNoIndexSettings: EsClusterContainer - private lazy val ror1_1Node = rorWithIndexConfig.nodes.head - private lazy val ror1_2Node = rorWithIndexConfig.nodes.tail.head - private lazy val ror2_1Node = rorWithNoIndexConfig.nodes.head + private lazy val ror1_1Node = rorWithIndexSettings.nodes.head + private lazy val ror1_2Node = rorWithIndexSettings.nodes.tail.head + private lazy val ror2_1Node = rorWithNoIndexSettings.nodes.head - private lazy val ror1WithIndexConfigAdminActionManager = new RorApiManager(clients.head.adminClient, esVersionUsed) - private lazy val rorWithNoIndexConfigAdminActionManager = new RorApiManager(clients.last.adminClient, esVersionUsed) + private lazy val ror1WithIndexSettingsAdminActionManager = new RorApiManager(clients.head.adminClient, esVersionUsed) + private lazy val rorWithNoIndexSettingsAdminActionManager = new RorApiManager(clients.last.adminClient, esVersionUsed) private lazy val adminSearchManager = new SearchManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) private lazy val adminIndexManager = new IndexManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) - private val testConfigEsDocumentId = "2" + private val testSettingsEsDocumentId = "2" protected val settingsReloadInterval: FiniteDuration = 5 seconds override lazy val esTargets = NonEmptyList.of(ror1_1Node, ror1_2Node, ror2_1Node) - override lazy val clusterContainers = NonEmptyList.of(rorWithIndexConfig, rorWithNoIndexConfig) + override lazy val clusterContainers = NonEmptyList.of(rorWithIndexSettings, rorWithNoIndexSettings) "An admin REST API" should { "provide a method for force refresh ROR settings" which { "is going to reload ROR core" when { - "in-index config is newer than current one" in { - rorWithNoIndexConfigAdminActionManager + "in-index settings is newer than current one" in { + rorWithNoIndexSettingsAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, settings = getResourceContent("/admin_api/readonlyrest_index.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() + val result = rorWithNoIndexSettingsAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -91,16 +91,16 @@ trait BaseAdminApiSuite )) } } - "return info that config is up to date" when { - "in-index config is the same as current one" in { - rorWithNoIndexConfigAdminActionManager + "return info that settings are up to date" when { + "in-index settings are the same as current one" in { + rorWithNoIndexSettingsAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, settings = getResourceContent("/admin_api/readonlyrest.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() + val result = rorWithNoIndexSettingsAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -112,9 +112,9 @@ trait BaseAdminApiSuite )) } } - "return info that in-index config does not exist" when { + "return info that in-index settings do not exist" when { "there is no in-index settings configured yet" in { - val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() + val result = rorWithNoIndexSettingsAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( s""" @@ -127,15 +127,15 @@ trait BaseAdminApiSuite } } "return info that cannot reload settings" when { - "config cannot be reloaded (eg. because LDAP is not achievable)" in { - rorWithNoIndexConfigAdminActionManager + "settings cannot be reloaded (eg. because LDAP is not achievable)" in { + rorWithNoIndexSettingsAdminActionManager .insertInIndexSettingsDirectlyToRorIndex( rorIndex = readonlyrestIndexName, settings = getResourceContent("/admin_api/readonlyrest_with_ldap.yml") ) .force() - val result = rorWithNoIndexConfigAdminActionManager.reloadRorSettings() + val result = rorWithNoIndexSettingsAdminActionManager.reloadRorSettings() result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -150,9 +150,9 @@ trait BaseAdminApiSuite } "provide a method for update in-index settings" which { "is going to reload ROR core and store new in-index settings" when { - "configuration is new and correct" in { + "settings are new and correct" in { def forceReload(rorSettingsResource: String) = { - val result = ror1WithIndexConfigAdminActionManager.updateRorInIndexSettings(getResourceContent(rorSettingsResource)) + val result = ror1WithIndexSettingsAdminActionManager.updateRorInIndexSettings(getResourceContent(rorSettingsResource)) result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -185,7 +185,7 @@ trait BaseAdminApiSuite forceReload("/admin_api/readonlyrest_first_update.yml") // after first reload only dev1 can access indices - Thread.sleep(settingsReloadInterval.plus(10 second).toMillis) // have to wait for ROR1_2 instance config reload + Thread.sleep(settingsReloadInterval.plus(10 second).toMillis) // have to wait for ROR1_2 instance settings reload val dev1ror1After1stReloadResults = dev1Ror1stInstanceSearchManager.search("test1_index") dev1ror1After1stReloadResults should have statusCode 200 val dev2ror1After1stReloadResults = dev2Ror1stInstanceSearchManager.search("test2_index") @@ -199,7 +199,7 @@ trait BaseAdminApiSuite forceReload("/admin_api/readonlyrest_second_update.yml") // after second reload dev1 & dev2 can access indices - Thread.sleep(settingsReloadInterval.plus(10 second).toMillis) // have to wait for ROR1_2 instance config reload + Thread.sleep(settingsReloadInterval.plus(10 second).toMillis) // have to wait for ROR1_2 instance settings reload val dev1ror1After2ndReloadResults = dev1Ror1stInstanceSearchManager.search("test1_index") dev1ror1After2ndReloadResults should have statusCode 200 val dev2ror1After2ndReloadResults = dev2Ror1stInstanceSearchManager.search("test2_index") @@ -211,9 +211,9 @@ trait BaseAdminApiSuite } } - "return info that config is up to date" when { - "in-index config is the same as provided one" in { - val result = ror1WithIndexConfigAdminActionManager + "return info that settings are up to date" when { + "in-index settings are the same as provided one" in { + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_index.yml")) assertSettingsInIndex(getResourceContent("/admin_api/readonlyrest_index.yml")) @@ -228,9 +228,9 @@ trait BaseAdminApiSuite )) } } - "return info that config is malformed" when { + "return info that settings are malformed" when { "invalid YAML is provided" in { - val result = ror1WithIndexConfigAdminActionManager + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_malformed.yml")) result should have statusCode 200 @@ -240,7 +240,7 @@ trait BaseAdminApiSuite } "return info that request is malformed" when { "settings key missing" in { - val result = ror1WithIndexConfigAdminActionManager + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettingsRaw(rawRequestBody = "{}") result should have statusCode 400 @@ -256,7 +256,7 @@ trait BaseAdminApiSuite } "return info that cannot reload" when { "ROR core cannot be reloaded" in { - val result = ror1WithIndexConfigAdminActionManager + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_with_ldap.yml")) result should have statusCode 200 @@ -274,7 +274,7 @@ trait BaseAdminApiSuite "provide a method for fetching current in-index settings" which { "return current settings" when { "there is one in index" in { - val result = ror1WithIndexConfigAdminActionManager + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_first_update.yml")) result should have statusCode 200 @@ -289,20 +289,20 @@ trait BaseAdminApiSuite assertSettingsInIndex(getResourceContent("/admin_api/readonlyrest_first_update.yml")) - val getIndexConfigResult = ror1WithIndexConfigAdminActionManager.getRorInIndexSettings + val getIndexSettingsResult = ror1WithIndexSettingsAdminActionManager.getRorInIndexSettings result should have statusCode 200 - getIndexConfigResult.responseJson("status").str should be("ok") - getIndexConfigResult.responseJson("message").str should be { + getIndexSettingsResult.responseJson("status").str should be("ok") + getIndexSettingsResult.responseJson("message").str should be { getResourceContent("/admin_api/readonlyrest_first_update.yml") } } } "return info that there is no in-index settings" when { "there is no index" in { - assertNoRorConfigInIndex(rorWithNoIndexConfigAdminActionManager) + assertNoRorSettingsInIndex(rorWithNoIndexSettingsAdminActionManager) } - "there is no config document in index" in { - val result = ror1WithIndexConfigAdminActionManager + "there are no settings document in index" in { + val result = ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_first_update.yml")) result should have statusCode 200 @@ -320,13 +320,13 @@ trait BaseAdminApiSuite val deleteResponse = adminDocumentManager.deleteByQuery(readonlyrestIndexName, matchAllQuery) deleteResponse should have statusCode 200 - assertNoRorConfigInIndex(rorWithNoIndexConfigAdminActionManager) + assertNoRorSettingsInIndex(rorWithNoIndexSettingsAdminActionManager) } } } "provide a method for fetching current file settings" which { "return current settings" in { - val result = ror1WithIndexConfigAdminActionManager.getRorFileSettings + val result = ror1WithIndexSettingsAdminActionManager.getRorFileSettings result should have statusCode 200 result.responseJson("status").str should be("ok") result.responseJson("message").str should be(getResourceContent("/admin_api/readonlyrest.yml")) @@ -355,20 +355,20 @@ trait BaseAdminApiSuite } } "return current test settings" when { - "should invalidate configuration when index removed" in { + "should invalidate settings when index removed" in { def forceReload(rorSettingsResource: String): Unit = { - val testConfig = getResourceContent(rorSettingsResource) - val configTtl = 30.minutes - updateRorTestConfig(rorClients.head, testConfig, configTtl) + val testSettings = getResourceContent(rorSettingsResource) + val settingsTtl = 30.minutes + updateRorTestSettings(rorClients.head, testSettings, settingsTtl) - // check if config is present in index + // check if settings are present in index assertTestSettingsInIndex( - expectedConfig = testConfig, - expectedTtl = 30 minutes + expectedSettings = testSettings, + expectedTtl = settingsTtl ) - eventually { // await until all nodes load config - rorClients.foreach(assertTestSettingsPresent(_, testConfig, "30 minutes")) + eventually { // await until all nodes load settings + rorClients.foreach(assertTestSettingsPresent(_, testSettings, "30 minutes")) } } @@ -387,46 +387,46 @@ trait BaseAdminApiSuite } // before first reload no user can access indices - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) - // reload config + // reload settings forceReload("/admin_api/readonlyrest_first_update_with_impersonation.yml") // check if impersonation works - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test1_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test1_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test2_index")) - // drop index containing ror config + // drop index containing ror settings val indexManager = new IndexManager(clients.head.basicAuthClient("admin", "container"), esVersionUsed) indexManager.removeIndex(readonlyrestIndexName).force() - eventually { // await until all nodes invalidate the config + eventually { // await until all nodes invalidate the settings rorClients.foreach { assertTestSettingsNotConfigured } } // check if impersonation is not configured - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) } - "configuration is valid and response without warnings" in { + "settings are valid and response without warnings" in { def forceReload(rorSettingsResource: String): Unit = { - val testConfig = getResourceContent(rorSettingsResource) - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + val testSettingsYaml = getResourceContent(rorSettingsResource) + updateRorTestSettings(rorClients.head, testSettingsYaml, 30 minutes) - assertTestSettingsInIndex(testConfig, 30 minutes) + assertTestSettingsInIndex(testSettingsYaml, 30 minutes) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => - assertTestSettingsPresent(rorApiManager, testConfig, "30 minutes") + assertTestSettingsPresent(rorApiManager, testSettingsYaml, "30 minutes") } } } @@ -446,37 +446,37 @@ trait BaseAdminApiSuite } // before first reload no user can access indices - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) // first reload forceReload("/admin_api/readonlyrest_first_update_with_impersonation.yml") // after first reload only dev1 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test1_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test1_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test2_index")) // second reload forceReload("/admin_api/readonlyrest_second_update_with_impersonation.yml") // after second reload dev1 & dev2 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(indexNotFound(_, "test1_index")) - dev2SearchManagers.foreach(allowedSearch(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertIndexNotFound(_, "test1_index")) + dev2SearchManagers.foreach(assertAllowedSearch(_, "test2_index")) } - "configuration is valid and response with warnings" in { + "settings are valid and response with warnings" in { val warningsJson = ujson.read( """ |[ | { | "block_name": "test1", | "rule_name": "auth_key_sha256", - | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this configuration", + | "message": "The rule contains fully hashed username and password. It doesn't support impersonation in this use case.", | "hint": "You can use second version of the rule and use not hashed username. Like that: `auth_key_sha256: USER_NAME:hash(PASSWORD)" | } |] @@ -484,16 +484,16 @@ trait BaseAdminApiSuite ) def forceReload(rorSettingsResource: String, warnings: ujson.Value): Unit = { - val testConfig = getResourceContent(rorSettingsResource) - updateRorTestConfig(rorClients.head, testConfig, 30 minutes, warnings) + val testSettingsYaml = getResourceContent(rorSettingsResource) + updateRorTestSettings(rorClients.head, testSettingsYaml, 30 minutes, warnings) - // check if config is present in index + // check if settings are present in index assertTestSettingsInIndex( - expectedConfig = testConfig, + expectedSettings = testSettingsYaml, expectedTtl = 30 minutes ) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => val response = rorApiManager.currentRorTestSettings response should have statusCode 200 @@ -510,16 +510,16 @@ trait BaseAdminApiSuite } // before reload no user can access indices - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) val rorSettingsResource = "/admin_api/readonlyrest_with_warnings.yml" forceReload(rorSettingsResource, warningsJson) - val testConfig = getResourceContent(rorSettingsResource) + val testSettings = getResourceContent(rorSettingsResource) rorClients.foreach { rorApiManager => assertTestSettingsPresent( rorApiManager, - testConfig, + testSettings, "30 minutes", warningsJson ) @@ -527,18 +527,18 @@ trait BaseAdminApiSuite // user with hashed credential cannot be impersonated dev1SearchManagers.foreach { - impersonationNotAllowed(_, "test1_index") + assertImpersonationNotAllowed(_, "test1_index") } } "return local users" in { - val testConfig = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + val testSettingsYaml = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") + updateRorTestSettings(rorClients.head, testSettingsYaml, 30 minutes) - assertTestSettingsInIndex(expectedConfig = testConfig, expectedTtl = 30 minutes) + assertTestSettingsInIndex(expectedSettings = testSettingsYaml, expectedTtl = 30 minutes) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { - assertTestSettingsPresent(_, testConfig, "30 minutes") + assertTestSettingsPresent(_, testSettingsYaml, "30 minutes") } } @@ -551,16 +551,16 @@ trait BaseAdminApiSuite } } } - "return info that configuration was invalidated" in { + "return info that settings were invalidated" in { def forceReload(rorSettingsResource: String): Unit = { - val testConfig = getResourceContent(rorSettingsResource) - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + val testSettings = getResourceContent(rorSettingsResource) + updateRorTestSettings(rorClients.head, testSettings, 30 minutes) - assertTestSettingsInIndex(expectedConfig = testConfig, expectedTtl = 30 minutes) + assertTestSettingsInIndex(expectedSettings = testSettings, expectedTtl = 30 minutes) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => - assertTestSettingsPresent(rorApiManager, testConfig, "30 minutes") + assertTestSettingsPresent(rorApiManager, testSettings, "30 minutes") } } } @@ -580,31 +580,31 @@ trait BaseAdminApiSuite } // before first reload no user can access indices - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) // first reload forceReload("/admin_api/readonlyrest_first_update_with_impersonation.yml") // after first reload only dev1 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test1_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test1_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test2_index")) // second reload val rorSettingsResource = "/admin_api/readonlyrest_second_update_with_impersonation.yml" forceReload(rorSettingsResource) // after second reload dev1 & dev2 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(indexNotFound(_, "test1_index")) - dev2SearchManagers.foreach(allowedSearch(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertIndexNotFound(_, "test1_index")) + dev2SearchManagers.foreach(assertAllowedSearch(_, "test2_index")) - invalidateRorTestConfig(rorClients.head) + invalidateRorTestSettings(rorClients.head) eventually { rorClients.foreach { rorApiManager => @@ -618,29 +618,30 @@ trait BaseAdminApiSuite } // after test core invalidation, impersonations requests should be rejected - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) } } - "provide a method for reload test config engine" which { + "provide a method for reload test settings engine" which { "is going to reload ROR test core with TTL" when { - "configuration is new and correct" in { - def forceReload(rorSettingsResource: String, configTtl: FiniteDuration, configTtlString: String): Unit = { - val testConfig = getResourceContent(rorSettingsResource) - updateRorTestConfig(rorClients.head, testConfig, configTtl) + "settings are new and correct" in { + // todo: do we need settingsTtlString? + def forceReload(rorSettingsResource: String, settingsTtl: FiniteDuration, settingsTtlString: String): Unit = { + val testSettings = getResourceContent(rorSettingsResource) + updateRorTestSettings(rorClients.head, testSettings, settingsTtl) - assertTestSettingsInIndex(expectedConfig = testConfig, expectedTtl = configTtl) + assertTestSettingsInIndex(expectedSettings = testSettings, expectedTtl = settingsTtl) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => - assertTestSettingsPresent(rorApiManager, testConfig, configTtlString) + assertTestSettingsPresent(rorApiManager, testSettings, settingsTtlString) } } } - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => assertTestSettingsNotConfigured(rorApiManager) } @@ -661,79 +662,79 @@ trait BaseAdminApiSuite } // before first reload no user can access indices - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) // first reload forceReload( rorSettingsResource = "/admin_api/readonlyrest_first_update_with_impersonation.yml", - configTtl = 30 minutes, - configTtlString = "30 minutes" + settingsTtl = 30 minutes, + settingsTtlString = "30 minutes" ) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => assertTestSettingsPresent( rorApiManager = rorApiManager, - testConfig = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml"), + testSettings = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml"), expectedTtl = "30 minutes" ) } } // after first reload only dev1 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test1_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test1_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test2_index")) // second reload val rorSettingsResource = "/admin_api/readonlyrest_second_update_with_impersonation.yml" - val configTtl = 15.seconds + val settingsTtl = 15.seconds forceReload( rorSettingsResource = rorSettingsResource, - configTtl = configTtl, - configTtlString = "15 seconds" + settingsTtl = settingsTtl, + settingsTtlString = "15 seconds" ) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => assertTestSettingsPresent( rorApiManager = rorApiManager, - testConfig = getResourceContent(rorSettingsResource), + testSettings = getResourceContent(rorSettingsResource), expectedTtl = "15 seconds" ) } } // after second reload dev1 & dev2 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(indexNotFound(_, "test1_index")) - dev2SearchManagers.foreach(allowedSearch(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertIndexNotFound(_, "test1_index")) + dev2SearchManagers.foreach(assertAllowedSearch(_, "test2_index")) // wait for test engine auto-destruction - Thread.sleep(configTtl.toMillis) + Thread.sleep(settingsTtl.toMillis) rorClients.foreach { rorApiManager => assertTestSettingsInvalidated(rorApiManager, getResourceContent(rorSettingsResource), "15 seconds") } - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) } - "configuration is up to date and new ttl is passed" in { - val testConfig = getResourceContent("/admin_api/readonlyrest_index.yml") - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) - assertTestSettingsInIndex(expectedConfig = testConfig, expectedTtl = 30 minutes) + "settings are up to date and new ttl is passed" in { + val testSettings = getResourceContent("/admin_api/readonlyrest_index.yml") + updateRorTestSettings(rorClients.head, testSettings, 30 minutes) + assertTestSettingsInIndex(expectedSettings = testSettings, expectedTtl = 30 minutes) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { - assertTestSettingsPresent(_, testConfig, "30 minutes") + assertTestSettingsPresent(_, testSettings, "30 minutes") } } @@ -747,12 +748,12 @@ trait BaseAdminApiSuite // wait for valid_to comparison purpose Thread.sleep(100) - updateRorTestConfig(rorClients.head, testConfig, 45 minutes) - assertTestSettingsInIndex(expectedConfig = testConfig, expectedTtl = 45 minutes) + updateRorTestSettings(rorClients.head, testSettings, 45 minutes) + assertTestSettingsInIndex(expectedSettings = testSettings, expectedTtl = 45 minutes) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { - assertTestSettingsPresent(_, testConfig, "45 minutes") + assertTestSettingsPresent(_, testSettings, "45 minutes") } } @@ -768,8 +769,8 @@ trait BaseAdminApiSuite } "return info that request is malformed" when { "ttl missing" in { - val config = getResourceContent("/admin_api/readonlyrest_index.yml") - val requestBody = s"""{"settings": "${escapeJava(config)}"}""" + val settings = getResourceContent("/admin_api/readonlyrest_index.yml") + val requestBody = s"""{"settings": "${escapeJava(settings)}"}""" rorClients.foreach { rorApiManager => val result = rorApiManager @@ -804,8 +805,8 @@ trait BaseAdminApiSuite } } "ttl value in invalid format" in { - val config = getResourceContent("/admin_api/readonlyrest_index.yml") - val requestBody = s"""{"settings": "${escapeJava(config)}", "ttl": "30 units"}""" + val settings = getResourceContent("/admin_api/readonlyrest_index.yml") + val requestBody = s"""{"settings": "${escapeJava(settings)}", "ttl": "30 units"}""" rorClients.foreach { rorApiManager => val result = rorApiManager @@ -823,7 +824,7 @@ trait BaseAdminApiSuite } } } - "return info that config is malformed" when { + "return info that settings are malformed" when { "invalid YAML is provided" in { rorClients.foreach { rorApiManager => val result = rorApiManager @@ -854,21 +855,21 @@ trait BaseAdminApiSuite } } } - "provide a method for test config engine invalidation" which { + "provide a method for test settings engine invalidation" which { "will destruct the engine on demand" in { def forceReload(rorSettingsResource: String): Unit = { - val testConfig = getResourceContent(rorSettingsResource) + val testSettings = getResourceContent(rorSettingsResource) - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + updateRorTestSettings(rorClients.head, testSettings, 30 minutes) assertTestSettingsInIndex( - expectedConfig = testConfig, + expectedSettings = testSettings, expectedTtl = 30 minutes ) - eventually { // await until all nodes load config + eventually { // await until all nodes load settings rorClients.foreach { rorApiManager => - assertTestSettingsPresent(rorApiManager, testConfig, "30 minutes") + assertTestSettingsPresent(rorApiManager, testSettings, "30 minutes") } } } @@ -887,30 +888,30 @@ trait BaseAdminApiSuite ) } - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) // first reload forceReload("/admin_api/readonlyrest_first_update_with_impersonation.yml") // after first reload only dev1 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test1_index")) - dev2SearchManagers.foreach(operationNotAllowed(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test1_index")) + dev2SearchManagers.foreach(assertOperationNotAllowed(_, "test2_index")) // second reload forceReload("/admin_api/readonlyrest_second_update_with_impersonation.yml") // after second reload dev1 & dev2 can access indices - dev1SearchManagers.foreach(allowedSearch(_, "test1_index")) - dev1SearchManagers.foreach(indexNotFound(_, "test2_index")) - dev2SearchManagers.foreach(indexNotFound(_, "test1_index")) - dev2SearchManagers.foreach(allowedSearch(_, "test2_index")) + dev1SearchManagers.foreach(assertAllowedSearch(_, "test1_index")) + dev1SearchManagers.foreach(assertIndexNotFound(_, "test2_index")) + dev2SearchManagers.foreach(assertIndexNotFound(_, "test1_index")) + dev2SearchManagers.foreach(assertAllowedSearch(_, "test2_index")) - invalidateRorTestConfig(rorClients.head) + invalidateRorTestSettings(rorClients.head) Thread.sleep(settingsReloadInterval.toMillis) // wait for engines reload @@ -918,33 +919,33 @@ trait BaseAdminApiSuite rorClients.foreach { rorApiManager => assertTestSettingsInvalidated( rorApiManager = rorApiManager, - testConfig = getResourceContent("/admin_api/readonlyrest_second_update_with_impersonation.yml"), + testSettingsYaml = getResourceContent("/admin_api/readonlyrest_second_update_with_impersonation.yml"), expectedTtl = "30 minutes" ) } // after test core invalidation, impersonations requests should be rejected - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev1SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test1_index")) - dev2SearchManagers.foreach(testSettingsNotConfigured(_, "test2_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev1SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test1_index")) + dev2SearchManagers.foreach(assertTestSettingsNotConfigured(_, "test2_index")) } } - "main ROR config and test ROR config coexistence check" when { + "main ROR settings and test ROR settings coexistence check" when { "get main ROR index settings" should { "return no index settings" when { - "no main and test config in the index" in { + "no main and test settings in the index" in { adminIndexManager.removeIndex(readonlyrestIndexName) rorClients.foreach { rorApiManager => - assertNoRorConfigInIndex(rorApiManager) + assertNoRorSettingsInIndex(rorApiManager) assertTestSettingsNotConfigured(rorApiManager) } } - "only test config in the index" in { - def forceReloadTestSettings(testConfig: String): Unit = { - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + "only test settings in the index" in { + def forceReloadTestSettings(testSettings: String): Unit = { + updateRorTestSettings(rorClients.head, testSettings, 30 minutes) assertTestSettingsInIndex( - expectedConfig = testConfig, + expectedSettings = testSettings, expectedTtl = 30 minutes ) } @@ -952,56 +953,56 @@ trait BaseAdminApiSuite adminIndexManager.removeIndex(readonlyrestIndexName) rorClients.foreach { rorApiManager => - assertNoRorConfigInIndex(rorApiManager) + assertNoRorSettingsInIndex(rorApiManager) assertTestSettingsNotConfigured(rorApiManager) } - val config = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") - forceReloadTestSettings(config) + val settings = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") + forceReloadTestSettings(settings) Thread.sleep(settingsReloadInterval.toMillis) // wait for engines reload rorClients.foreach { rorApiManager => - assertNoRorConfigInIndex(rorApiManager) + assertNoDocumentWithMainRorSettingsInIndex(rorApiManager) assertTestSettingsPresent( rorApiManager, - testConfig = config, + testSettings = settings, expectedTtl = "30 minutes" ) } } } "return index settings" when { - "only main config in the index" in { - def forceReloadMainSettings(config: String) = { - updateRorMainConfig(rorClients.head, config) - assertSettingsInIndex(expectedConfig = config) + "only main settings in the index" in { + def forceReloadMainSettings(mainSettingsYaml: String) = { + updateRorMainSettings(rorClients.head, mainSettingsYaml) + assertSettingsInIndex(expectedSettings = mainSettingsYaml) } adminIndexManager.removeIndex(readonlyrestIndexName) rorClients.foreach { rorApiManager => - assertNoRorConfigInIndex(rorApiManager) + assertNoRorSettingsInIndex(rorApiManager) assertTestSettingsNotConfigured(rorApiManager) } - val config = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") - forceReloadMainSettings(config) + val settings = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") + forceReloadMainSettings(settings) rorClients.foreach { rorApiManager => - assertInIndexConfigPresent(rorApiManager, config) + assertInIndexSettingsPresent(rorApiManager, settings) assertTestSettingsNotConfigured(rorApiManager) } } - "main and test configs in the index" in { - def forceReloadMainSettings(config: String) = { - updateRorMainConfig(rorClients.head, config) - assertSettingsInIndex(expectedConfig = config) + "main and test settings in the index" in { + def forceReloadMainSettings(settings: String) = { + updateRorMainSettings(rorClients.head, settings) + assertSettingsInIndex(expectedSettings = settings) } - def forceReloadTestSettings(testConfig: String): Unit = { - updateRorTestConfig(rorClients.head, testConfig, 30 minutes) + def forceReloadTestSettings(testSettings: String): Unit = { + updateRorTestSettings(rorClients.head, testSettings, 30 minutes) assertTestSettingsInIndex( - expectedConfig = testConfig, + expectedSettings = testSettings, expectedTtl = 30 minutes ) } @@ -1009,18 +1010,18 @@ trait BaseAdminApiSuite adminIndexManager.removeIndex(readonlyrestIndexName) rorClients.foreach { rorApiManager => - assertNoRorConfigInIndex(rorApiManager) + assertNoRorSettingsInIndex(rorApiManager) assertTestSettingsNotConfigured(rorApiManager) } - val config = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") - forceReloadMainSettings(config) - forceReloadTestSettings(config) + val settings = getResourceContent("/admin_api/readonlyrest_first_update_with_impersonation.yml") + forceReloadMainSettings(settings) + forceReloadTestSettings(settings) Thread.sleep(settingsReloadInterval.toMillis) // wait for engines reload rorClients.foreach { client => - assertInIndexConfigPresent(client, config = config) - assertTestSettingsPresent(client, testConfig = config, expectedTtl = "30 minutes") + assertInIndexSettingsPresent(client, settings) + assertTestSettingsPresent(client, testSettings = settings, expectedTtl = "30 minutes") } } } @@ -1029,8 +1030,8 @@ trait BaseAdminApiSuite } override protected def beforeEach(): Unit = { - // back to configuration loaded on container start - rorWithNoIndexConfigAdminActionManager + // back to settings loaded on container start + rorWithNoIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest.yml")) .force() @@ -1038,11 +1039,11 @@ trait BaseAdminApiSuite adminIndexManager.removeIndex(readonlyrestIndexName) - ror1WithIndexConfigAdminActionManager + ror1WithIndexSettingsAdminActionManager .updateRorInIndexSettings(getResourceContent("/admin_api/readonlyrest_index.yml")) .force() - eventually { // await until all nodes invalidate the config + eventually { // await until all nodes invalidate the settings rorClients.foreach(assertTestSettingsNotConfigured) } } @@ -1062,7 +1063,7 @@ trait BaseAdminApiSuite } } - private def assertSettingsInIndex(expectedConfig: String) = { + private def assertSettingsInIndex(expectedSettings: String) = { val indexSearchResponse = adminSearchManager.search(readonlyrestIndexName) indexSearchResponse should have statusCode 200 val indexSearchHits = indexSearchResponse.responseJson("hits")("hits").arr.toList @@ -1072,29 +1073,32 @@ trait BaseAdminApiSuite }.value val testSettingsDocumentContent = testSettingsDocumentHit("_source") - testSettingsDocumentContent("settings").str should be(expectedConfig) + testSettingsDocumentContent("settings").str should be(expectedSettings) } - private def assertTestSettingsInIndex(expectedConfig: String, expectedTtl: FiniteDuration) = { + private def assertTestSettingsInIndex(expectedSettings: String, expectedTtl: FiniteDuration) = { val indexSearchResponse = adminSearchManager.search(readonlyrestIndexName) indexSearchResponse should have statusCode 200 val indexSearchHits = indexSearchResponse.responseJson("hits")("hits").arr.toList indexSearchHits.size should be >= 1 // at least main document or test document should be present - val testSettingsDocumentHit = indexSearchHits.find { searchResult => - (searchResult("_index").str, searchResult("_id").str) === (readonlyrestIndexName, testConfigEsDocumentId) - }.value + val testSettingsDocumentHit = indexSearchHits + .find { searchResult => + (searchResult("_index").str, searchResult("_id").str) === (readonlyrestIndexName, testSettingsEsDocumentId) + } + .value val testSettingsDocumentContent = testSettingsDocumentHit("_source") - testSettingsDocumentContent("settings").str should be(expectedConfig) + testSettingsDocumentContent("settings").str should be(expectedSettings) testSettingsDocumentContent("expiration_ttl_millis").str should be(expectedTtl.toMillis.toString) testSettingsDocumentContent("expiration_timestamp").str.isInIsoDateTimeFormat should be(true) - val mocksContent = ujson.read(testSettingsDocumentContent("auth_services_mocks").str) + + val mocksContent = testSettingsDocumentContent("auth_services_mocks") mocksContent("ldapMocks").obj.isEmpty should be(true) mocksContent("externalAuthenticationMocks").obj.isEmpty should be(true) mocksContent("externalAuthorizationMocks").obj.isEmpty should be(true) } - private def assertNoRorConfigInIndex(rorApiManager: RorApiManager) = { + private def assertNoRorSettingsInIndex(rorApiManager: RorApiManager) = { val result = rorApiManager.getRorInIndexSettings result should have statusCode 200 result.responseJson should be(ujson.read( @@ -1107,11 +1111,24 @@ trait BaseAdminApiSuite )) } - private def assertInIndexConfigPresent(rorApiManager: RorApiManager, config: String) = { - val getIndexConfigResult = rorApiManager.getRorInIndexSettings - getIndexConfigResult should have statusCode 200 - getIndexConfigResult.responseJson("status").str should be("ok") - getIndexConfigResult.responseJson("message").str should be(config) + private def assertNoDocumentWithMainRorSettingsInIndex(rorApiManager: RorApiManager) = { + val result = rorApiManager.getRorInIndexSettings + result should have statusCode 200 + result.responseJson should be(ujson.read( + """ + |{ + | "status": "ko", + | "message": "Cannot found document with ReadonlyREST settings" + |} + |""".stripMargin + )) + } + + private def assertInIndexSettingsPresent(rorApiManager: RorApiManager, settings: String) = { + val result = rorApiManager.getRorInIndexSettings + result should have statusCode 200 + result.responseJson("status").str should be("ok") + result.responseJson("message").str should be(settings) } private def assertTestSettingsNotConfigured(rorApiManager: RorApiManager) = { @@ -1128,34 +1145,34 @@ trait BaseAdminApiSuite } private def assertTestSettingsPresent(rorApiManager: RorApiManager, - testConfig: String, + testSettings: String, expectedTtl: String, expectedWarningsJson: Value = ujson.read("[]")) = { val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_PRESENT") - response.responseJson("settings").str should be(testConfig) + response.responseJson("settings").str should be(testSettings) response.responseJson("ttl").str should be(expectedTtl) response.responseJson("valid_to").str.isInIsoDateTimeFormat should be(true) response.responseJson("warnings") should be(expectedWarningsJson) } private def assertTestSettingsInvalidated(rorApiManager: RorApiManager, - testConfig: String, + testSettingsYaml: String, expectedTtl: String) = { val response = rorApiManager.currentRorTestSettings response should have statusCode 200 response.responseJson("status").str should be("TEST_SETTINGS_INVALIDATED") response.responseJson("message").str should be("ROR Test settings are invalidated") - response.responseJson("settings").str should be(testConfig) + response.responseJson("settings").str should be(testSettingsYaml) response.responseJson("ttl").str should be(expectedTtl) } - private def updateRorTestConfig(rorApiManager: RorApiManager, - testConfig: String, - configTtl: FiniteDuration, - expectedWarningsJson: Value = ujson.read("[]")) = { - val response = rorApiManager.updateRorTestSettings(testConfig, configTtl) + private def updateRorTestSettings(rorApiManager: RorApiManager, + testSettingsYaml: String, + settingsTtl: FiniteDuration, + expectedWarningsJson: Value = ujson.read("[]")) = { + val response = rorApiManager.updateRorTestSettings(testSettingsYaml, settingsTtl) response should have statusCode 200 response.responseJson("status").str should be("OK") response.responseJson("message").str should be("updated settings") @@ -1163,8 +1180,8 @@ trait BaseAdminApiSuite response.responseJson("warnings") should be(expectedWarningsJson) } - private def updateRorMainConfig(rorApiManager: RorApiManager, config: String) = { - val result = rorApiManager.updateRorInIndexSettings(config) + private def updateRorMainSettings(rorApiManager: RorApiManager, mainSettingsYaml: String) = { + val result = rorApiManager.updateRorInIndexSettings(mainSettingsYaml) result should have statusCode 200 result.responseJson should be(ujson.read( """ @@ -1176,7 +1193,7 @@ trait BaseAdminApiSuite )) } - private def invalidateRorTestConfig(rorApiManager: RorApiManager) = { + private def invalidateRorTestSettings(rorApiManager: RorApiManager) = { val response = rorApiManager.invalidateRorTestSettings() response should have statusCode 200 response.responseJson should be(ujson.read( @@ -1189,7 +1206,7 @@ trait BaseAdminApiSuite )) } - private def testSettingsNotConfigured(sm: SearchManager, indexName: String) = { + private def assertTestSettingsNotConfigured(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 403 results.responseJson should be(ujson.read( @@ -1213,12 +1230,12 @@ trait BaseAdminApiSuite )) } - private def allowedSearch(sm: SearchManager, indexName: String) = { + private def assertAllowedSearch(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 200 } - private def indexNotFound(sm: SearchManager, indexName: String) = { + private def assertIndexNotFound(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 404 @@ -1258,7 +1275,7 @@ trait BaseAdminApiSuite )) } - private def operationNotAllowed(sm: SearchManager, indexName: String) = { + private def assertOperationNotAllowed(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 403 results.responseJson should be(ujson.read( @@ -1281,7 +1298,7 @@ trait BaseAdminApiSuite )) } - private def impersonationNotAllowed(sm: SearchManager, indexName: String) = { + private def assertImpersonationNotAllowed(sm: SearchManager, indexName: String) = { val results = sm.search(indexName) results should have statusCode 403 results.responseJson should be(ujson.read( From 1e19a6efac095adae06723405e405add07f73ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 12:10:23 +0100 Subject: [PATCH 074/103] wip --- .../blocks/ImpersonationWarning.scala | 2 +- .../suites/AdminApiAuthMockSuite.scala | 6 +-- .../suites/ImpersonationSuite.scala | 2 +- .../suites/RemoteReindexSuite.scala | 4 +- .../LocalClusterAuditingToolsSuite.scala | 51 ++++++++++--------- .../RemoteClusterAuditingToolsSuite.scala | 2 +- ...sterWithRorNodesAndInternodeSslSuite.scala | 2 +- 7 files changed, 35 insertions(+), 34 deletions(-) diff --git a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala index 23c3d39cff..f80e5d78e1 100644 --- a/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala +++ b/core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/ImpersonationWarning.scala @@ -164,7 +164,7 @@ object ImpersonationWarning { Some(ImpersonationWarning( block = blockName, ruleName = rule.name, - message = nes("The rule contains fully hashed username and password. It doesn't support impersonation in this use case.."), + message = nes("The rule contains fully hashed username and password. It doesn't support impersonation in this use case."), hint = s"You can use second version of the rule and use not hashed username. Like that: `${rule.name.show}: USER_NAME:hash(PASSWORD)" )) case _: HashedCredentials.HashedOnlyPassword => diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala index 900bcb3478..f665df4a0d 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/AdminApiAuthMockSuite.scala @@ -191,9 +191,9 @@ class AdminApiAuthMockSuite )) rorClients.foreach { rorApiManager => - val testConfigResponse = rorApiManager.currentRorTestSettings - testConfigResponse.responseJson("status").str should be("TEST_SETTINGS_PRESENT") - testConfigResponse.responseJson("warnings") should be( + val testSettingsResponse = rorApiManager.currentRorTestSettings + testSettingsResponse.responseJson("status").str should be("TEST_SETTINGS_PRESENT") + testSettingsResponse.responseJson("warnings") should be( ujson.read( s""" |[ diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala index 1b46e1c011..81716f9de4 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/ImpersonationSuite.scala @@ -55,7 +55,7 @@ class ImpersonationSuite super.beforeAll() loadTestSettings() rorApiManager - .updateRorInIndexSettings( // In a test, the main engine config should be different from the test config to prevent accidental use of the main engine + .updateRorInIndexSettings( // In a test, the main settings engine should be different from the test settings to prevent accidental use of the main engine s""" |readonlyrest: | access_control_rules: diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala index 348bf0ba00..861c602b4d 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RemoteReindexSuite.scala @@ -42,7 +42,7 @@ class RemoteReindexSuite with CustomScalaTestMatchers { override implicit val rorSettingsFileName: String = "/reindex_multi_containers/readonlyrest_dest_es.yml" - private val sourceEsRorConfigFileName = "/reindex_multi_containers/readonlyrest_source_es.yml" + private val sourceEsRorSettingsFileName = "/reindex_multi_containers/readonlyrest_source_es.yml" private lazy val sourceEsCluster = createLocalClusterContainer( EsClusterSettings.create( @@ -56,7 +56,7 @@ class RemoteReindexSuite }, securityType = SecurityType.RorSecurity( ReadonlyRestPlugin.Config.Attributes.default.copy( - rorSettingsFileName = RemoteReindexSuite.this.sourceEsRorConfigFileName, + rorSettingsFileName = RemoteReindexSuite.this.sourceEsRorSettingsFileName, restSsl = Enabled.No )) ) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala index 6a9b03baa0..0908db6cc8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala @@ -53,7 +53,7 @@ class LocalClusterAuditingToolsSuite override protected def baseAuditDataStreamName: Option[String] = Option.when(Version.greaterOrEqualThan(esVersionUsed, 7, 9, 0))("audit_data_stream") - // Adding the ES cluster fields is disabled in the /enabled_auditing_tools/readonlyrest.yml config file (`DefaultAuditLogSerializerV1` is used) + // Adding the ES cluster fields is disabled in the /enabled_auditing_tools/readonlyrest.yml settings file (`DefaultAuditLogSerializerV1` is used) override def assertForEveryAuditEntry(entry: JSON): Unit = { entry.obj.get("es_node_name") shouldBe None entry.obj.get("es_cluster_name") shouldBe None @@ -61,13 +61,13 @@ class LocalClusterAuditingToolsSuite "ES" should { "submit audit entries" when { - "first request uses V1 serializer, then ROR config is reloaded and second request uses V2 serializer" in { + "first request uses V1 serializer, then ROR settings is reloaded and second request uses V2 serializer" in { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") performAndAssertExampleSearchRequest(indexManager) - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV2") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV2") performAndAssertExampleSearchRequest(indexManager) forEachAuditManager { adminAuditManager => @@ -75,7 +75,7 @@ class LocalClusterAuditingToolsSuite val auditEntries = adminAuditManager.getEntries.force().jsons // On Linux we could assert number of entries equal to 2. - // On Windows reloading config sometimes takes a little longer, + // On Windows reloading settings sometimes takes a little longer, // and there are 3 or more messages (from before reload, so not important) auditEntries.size should be >= 2 auditEntries.exists(entry => @@ -98,12 +98,12 @@ class LocalClusterAuditingToolsSuite ) shouldBe true } } - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") } "using ReportingAllEventsAuditLogSerializer" in { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.FullAuditLogSerializer") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.FullAuditLogSerializer") performAndAssertExampleSearchRequest(indexManager) forEachAuditManager { adminAuditManager => @@ -126,14 +126,14 @@ class LocalClusterAuditingToolsSuite auditEntries.exists(entry => entry("path").str == "/audit_index/_search/") shouldBe true } } - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") // This test uses serializer, that reports all events. We need to wait a moment, to ensure that there will be no more events using that serializer Thread.sleep(3000) } "using ReportingAllEventsWithQueryAuditLogSerializer" in { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.FullAuditLogWithQuerySerializer") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.FullAuditLogWithQuerySerializer") performAndAssertExampleSearchRequest(indexManager) forEachAuditManager { adminAuditManager => @@ -155,15 +155,15 @@ class LocalClusterAuditingToolsSuite auditEntries.exists(entry => entry("path").str == "/audit_index/_search/") shouldBe true } } - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") // This test uses serializer, that reports all events. We need to wait a moment, to ensure that there will be no more events using that serializer Thread.sleep(3000) } "using ConfigurableQueryAuditLogSerializer" in { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) - // Change config to use configurable serializer and perform the request - updateRorConfig( + // Change setting to use configurable serializer and perform the request + updateRorSettings( originalString = """type: "static"""", newString = """type: "configurable"""", ) @@ -186,7 +186,7 @@ class LocalClusterAuditingToolsSuite } // Disable audit for Rule 1, clean managers, perform second request - updateRorConfig( + updateRorSettings( "enabled: true ## twitter audit toggle", "enabled: false ## twitter audit toggle", ) @@ -200,19 +200,19 @@ class LocalClusterAuditingToolsSuite auditEntries.size shouldBe 0 } - // Restore the default config - updateRorConfig( + // Restore the default settings + updateRorSettings( "enabled: false ## twitter audit toggle", "enabled: true ## twitter audit toggle", ) - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") } "using ECS serializer" in { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) // We need to create a new index with a different name for this test, because the ECS schema // is not compatible with the Json object created by other serializers in previous tests. val ecsAuditIndexName = "ecs_audit_index" - updateRorConfig( + updateRorSettings( replacements = Map( """type: "static"""" -> """type: "ecs"""", "audit_index" -> ecsAuditIndexName, @@ -259,7 +259,7 @@ class LocalClusterAuditingToolsSuite entry("labels")("ror_detailed_reason").str == "{ name: 'Rule 1', policy: ALLOW, rules: [auth_key, methods, indices]" } shouldBe true } - updateRorConfigToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") + updateRorSettingsToUseSerializer("tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1") } } } @@ -269,15 +269,16 @@ class LocalClusterAuditingToolsSuite response should have statusCode 200 } - private def updateRorConfigToUseSerializer(serializer: String) = updateRorConfig( - originalString = """class_name: "tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1"""", - newString = s"""class_name: "$serializer"""" - ) + private def updateRorSettingsToUseSerializer(serializer: String): Unit = + updateRorSettings( + originalString = """class_name: "tech.beshu.ror.audit.instances.DefaultAuditLogSerializerV1"""", + newString = s"""class_name: "$serializer"""" + ) - private def updateRorConfig(originalString: String, newString: String): Unit = - updateRorConfig(Map(originalString -> newString)) + private def updateRorSettings(originalString: String, newString: String): Unit = + updateRorSettings(Map(originalString -> newString)) - private def updateRorConfig(replacements: Map[String, String]): Unit = { + private def updateRorSettings(replacements: Map[String, String]): Unit = { val initialConfig = getResourceContent(rorSettingsFileName) val modifiedConfig = replacements.foldLeft(initialConfig) { case (soFar, (originalString, newString)) => soFar.replace(originalString, newString) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala index 0a653e2c0d..1a55125927 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala @@ -93,7 +93,7 @@ class RemoteClusterAuditingToolsSuite override protected def baseAuditDataStreamName: Option[String] = Option.when(isDataStreamSupported)("audit_data_stream") - // Adding the ES cluster fields is enabled in the /cluster_auditing_tools/readonlyrest.yml config file (`DefaultAuditLogSerializerV2` is used) + // Adding the ES cluster fields is enabled in the /cluster_auditing_tools/readonlyrest.yml settings file (`DefaultAuditLogSerializerV2` is used) override def assertForEveryAuditEntry(entry: JSON): Unit = { entry("es_node_name").str shouldBe "ROR_SINGLE_1" entry("es_cluster_name").str shouldBe "ROR_SINGLE" diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala index 31a9f1c468..421df3d4d8 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/XpackClusterWithRorNodesAndInternodeSslSuite.scala @@ -77,7 +77,7 @@ trait XpackClusterWithRorNodesAndInternodeSslSuite response should have statusCode 200 } - "ROR config reload can be done" in { + "ROR settings reload can be done" in { val rorApiManager = new RorApiManager(clusterContainer.nodes.head.adminClient, esVersion = esVersionUsed) val updateResult = rorApiManager From 38bb955caa62fe7db3bbf5b374b4ab18913a9b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 12:20:49 +0100 Subject: [PATCH 075/103] clean up --- es818x/plugin-metadata/entitlement-policy.yaml | 4 ---- es90x/plugin-metadata/entitlement-policy.yaml | 6 ++++++ es91x/plugin-metadata/entitlement-policy.yaml | 6 ++++++ es92x/plugin-metadata/entitlement-policy.yaml | 6 ++++++ .../src/main/resources/log4j2_es_7.10_and_newer.properties | 2 +- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/es818x/plugin-metadata/entitlement-policy.yaml b/es818x/plugin-metadata/entitlement-policy.yaml index 3f59d734d4..ec9ea439be 100644 --- a/es818x/plugin-metadata/entitlement-policy.yaml +++ b/es818x/plugin-metadata/entitlement-policy.yaml @@ -9,10 +9,6 @@ ALL-UNNAMED: mode: "read" - path: "/proc/sys/net/core/somaxconn" mode: read - - path: "/usr/share/elasticsearch/.aws/config" - mode: read - - path: "/usr/share/elasticsearch/.aws/credentials" - mode: read - manage_threads - inbound_network - outbound_network \ No newline at end of file diff --git a/es90x/plugin-metadata/entitlement-policy.yaml b/es90x/plugin-metadata/entitlement-policy.yaml index e48762faa8..ec9ea439be 100644 --- a/es90x/plugin-metadata/entitlement-policy.yaml +++ b/es90x/plugin-metadata/entitlement-policy.yaml @@ -3,6 +3,12 @@ ALL-UNNAMED: - relative_path: ../ relative_to: config mode: read + - path: "/etc/os-release" + mode: "read" + - path: "/usr/lib/os-release" + mode: "read" + - path: "/proc/sys/net/core/somaxconn" + mode: read - manage_threads - inbound_network - outbound_network \ No newline at end of file diff --git a/es91x/plugin-metadata/entitlement-policy.yaml b/es91x/plugin-metadata/entitlement-policy.yaml index e48762faa8..ec9ea439be 100644 --- a/es91x/plugin-metadata/entitlement-policy.yaml +++ b/es91x/plugin-metadata/entitlement-policy.yaml @@ -3,6 +3,12 @@ ALL-UNNAMED: - relative_path: ../ relative_to: config mode: read + - path: "/etc/os-release" + mode: "read" + - path: "/usr/lib/os-release" + mode: "read" + - path: "/proc/sys/net/core/somaxconn" + mode: read - manage_threads - inbound_network - outbound_network \ No newline at end of file diff --git a/es92x/plugin-metadata/entitlement-policy.yaml b/es92x/plugin-metadata/entitlement-policy.yaml index e48762faa8..ec9ea439be 100644 --- a/es92x/plugin-metadata/entitlement-policy.yaml +++ b/es92x/plugin-metadata/entitlement-policy.yaml @@ -3,6 +3,12 @@ ALL-UNNAMED: - relative_path: ../ relative_to: config mode: read + - path: "/etc/os-release" + mode: "read" + - path: "/usr/lib/os-release" + mode: "read" + - path: "/proc/sys/net/core/somaxconn" + mode: read - manage_threads - inbound_network - outbound_network \ No newline at end of file diff --git a/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties b/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties index 3dcb296a30..b219fe63f9 100644 --- a/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties +++ b/tests-utils/src/main/resources/log4j2_es_7.10_and_newer.properties @@ -85,4 +85,4 @@ appender.header_warning.type = HeaderWarningAppender appender.header_warning.name = header_warning logger.ror_ldap.name=tech.beshu.ror -logger.ror_ldap.level=debug \ No newline at end of file +logger.ror_ldap.level=info \ No newline at end of file From 52cc707cef951dbf0bdab9fb17dc592af8eca404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 12:59:25 +0100 Subject: [PATCH 076/103] review fixes --- .../tech/beshu/ror/api/MainSettingsApi.scala | 2 +- .../tech/beshu/ror/boot/RorInstance.scala | 26 ++++---- .../SettingsRelatedCreatorsAndLoaders.scala | 8 +-- .../MainSettingsBasedReloadableEngine.scala | 2 +- .../TestSettingsBasedReloadableEngine.scala | 10 +-- .../main/scala/tech/beshu/ror/implicits.scala | 18 ++--- .../beshu/ror/settings/RorProperties.scala | 8 +-- .../es/EsConfigBasedRorSettings.scala | 4 +- ...a => RorCoreSettingsLoadingStrategy.scala} | 22 +++---- .../ror/settings/es/RorSslSettings.scala | 2 +- .../settings/ror/loader/RetryStrategy.scala | 8 +-- .../ror/source/FileSettingsSource.scala | 8 +-- .../ror/source/IndexSettingsSource.scala | 14 ++-- .../settings/ror/source/SettingsSource.scala | 22 +++---- .../elasticsearch.yml | 0 .../readonlyrest_index.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../custom_index_defined/elasticsearch.yml | 0 .../custom_index_defined/readonlyrest.yml | 0 .../no_index_defined}/elasticsearch.yml | 0 .../no_index_defined/readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest_index.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../readonlyrest_index.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../updated_readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../readonlyrest_index.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../elasticsearch.yml | 0 .../readonlyrest.yml | 0 .../readonlyrest_first.yml | 0 .../readonlyrest_initial.yml | 0 .../readonlyrest_second.yml | 0 .../IndexSettingsRelatedRorCoreTest.scala | 12 ++-- .../unit/boot/ReadonlyRestStartingTests.scala | 66 +++++++++---------- .../unit/settings/es/RorSslSettingsTest.scala | 4 +- .../suites/RorStartingResponseCodeSuite.scala | 8 +-- .../LocalClusterAuditingToolsSuite.scala | 8 +-- .../RemoteClusterAuditingToolsSuite.scala | 4 +- .../suites/base/BaseAuditingToolsSuite.scala | 30 ++++----- 57 files changed, 140 insertions(+), 146 deletions(-) rename core/src/main/scala/tech/beshu/ror/settings/es/{LoadingRorCoreStrategySettings.scala => RorCoreSettingsLoadingStrategy.scala} (88%) rename core/src/test/resources/boot_tests/{bad_index_config => bad_index_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{bad_index_config => bad_index_settings}/readonlyrest_index.yml (100%) rename core/src/test/resources/boot_tests/{es_api_ssl_settings_in_readonlyrest_config => es_api_ssl_settings_in_readonlyrest_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{es_api_ssl_settings_in_readonlyrest_config => es_api_ssl_settings_in_readonlyrest_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{forced_file_loading_bad_config => forced_file_loading_bad_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{forced_file_loading_bad_config => forced_file_loading_bad_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{forced_file_loading_malformed_config => forced_file_loading_malformed_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{forced_file_loading_malformed_config => forced_file_loading_malformed_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config => index_settings}/custom_index_defined/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config => index_settings}/custom_index_defined/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{config_reloading => index_settings/no_index_defined}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config => index_settings}/no_index_defined/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config/no_index_defined => index_settings_available_file_settings_not_provided}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config_available_file_config_not_provided => index_settings_available_file_settings_not_provided}/readonlyrest_index.yml (100%) rename core/src/test/resources/boot_tests/{index_config_available_file_config_not_provided => index_settings_available_file_settings_provided}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config_available_file_config_provided => index_settings_available_file_settings_provided}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config_available_file_config_provided => index_settings_available_file_settings_provided}/readonlyrest_index.yml (100%) rename core/src/test/resources/boot_tests/{index_config_available_file_config_provided => index_settings_not_exists_bad_file_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config_not_exists_bad_file_config => index_settings_not_exists_bad_file_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config_not_exists_malformed_file_config => index_settings_not_exists_malformed_file_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config_not_exists_malformed_file_config => index_settings_not_exists_malformed_file_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config_not_exists_bad_file_config => index_settings_reloading}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{index_config_reloading => index_settings_reloading}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config_reloading => index_settings_reloading}/updated_readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{internode_ssl_settings_in_readonlyrest_config => internode_ssl_settings_in_readonlyrest_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{internode_ssl_settings_in_readonlyrest_config => internode_ssl_settings_in_readonlyrest_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{index_config_reloading => malformed_index_settings}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{malformed_index_config => malformed_index_settings}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{malformed_index_config => malformed_index_settings}/readonlyrest_index.yml (100%) rename core/src/test/resources/boot_tests/{no_index_config_file_config_provided => no_index_settings_file_settings_provided}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{no_index_config_file_config_provided => no_index_settings_file_settings_provided}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{malformed_index_config => settings_reloading}/elasticsearch.yml (100%) rename core/src/test/resources/boot_tests/{config_reloading => settings_reloading}/readonlyrest.yml (100%) rename core/src/test/resources/boot_tests/{config_reloading => settings_reloading}/readonlyrest_first.yml (100%) rename core/src/test/resources/boot_tests/{config_reloading => settings_reloading}/readonlyrest_initial.yml (100%) rename core/src/test/resources/boot_tests/{config_reloading => settings_reloading}/readonlyrest_second.yml (100%) diff --git a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala index d6947c233a..28ae1ac9f0 100644 --- a/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala +++ b/core/src/main/scala/tech/beshu/ror/api/MainSettingsApi.scala @@ -31,7 +31,7 @@ import tech.beshu.ror.boot.RorInstance.{IndexSettingsReloadError, RawSettingsRel import tech.beshu.ror.boot.{RorInstance, RorSchedulers} import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.ror.source.IndexSettingsSource.LoadingError.IndexNotFound -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError.SourceSpecificError import tech.beshu.ror.settings.ror.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings, RawRorSettingsYamlParser} import tech.beshu.ror.utils.CirceOps.toCirceErrorOps diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala index 88a3102e16..e3d95bc477 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorInstance.scala @@ -29,11 +29,11 @@ import tech.beshu.ror.accesscontrol.factory.RorDependencies import tech.beshu.ror.api.{AuthMockApi, MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.boot.engines.Engines -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings -import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategySettings} +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, RorCoreSettingsLoadingStrategy} import tech.beshu.ror.settings.ror.source.IndexSettingsSource -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError import tech.beshu.ror.settings.ror.{MainRorSettings, RawRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -180,7 +180,7 @@ object RorInstance { boot = boot, esConfigBasedRorSettings = esConfigBasedRorSettings, creators = creators, - mode = modeFrom(esConfigBasedRorSettings.loadingRorCoreStrategy), + mode = modeFrom(esConfigBasedRorSettings.rorCoreSettingsLoadingStrategy), mainInitialEngine = mainEngine, mainReloadInProgress = isReloadInProgressSemaphore, testInitialEngine = testEngine, @@ -188,13 +188,13 @@ object RorInstance { ) } - private def modeFrom(strategy: LoadingRorCoreStrategySettings) = { + private def modeFrom(strategy: RorCoreSettingsLoadingStrategy) = { strategy match { - case LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings => + case RorCoreSettingsLoadingStrategy.ForceLoadingFromFileSettings => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => + case RorCoreSettingsLoadingStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Disabled) => Mode.NoPeriodicIndexCheck - case LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Enabled(refreshInterval)) => + case RorCoreSettingsLoadingStrategy.LoadFromIndexWithFileFallback(_, CoreRefreshSettings.Enabled(refreshInterval)) => Mode.WithPeriodicIndexCheck(refreshInterval) } } @@ -210,13 +210,13 @@ object RorInstance { object IndexSettingsReloadWithUpdateError { final case class ReloadError(undefined: RawSettingsReloadError) extends IndexSettingsReloadWithUpdateError - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + final case class IndexSettingsSavingError(underlying: SettingsSavingError[IndexSettingsSource.SavingError]) extends IndexSettingsReloadWithUpdateError } sealed trait IndexSettingsReloadError object IndexSettingsReloadError { - final case class IndexLoadingSettingsError(underlying: LoadingSettingsError[IndexSettingsSource.LoadingError]) + final case class IndexLoadingSettingsError(underlying: SettingsLoadingError[IndexSettingsSource.LoadingError]) extends IndexSettingsReloadError final case class ReloadError(underlying: RawSettingsReloadError) extends IndexSettingsReloadError @@ -224,7 +224,7 @@ object RorInstance { sealed trait IndexSettingsUpdateError object IndexSettingsUpdateError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + final case class IndexSettingsSavingError(underlying: SettingsSavingError[IndexSettingsSource.SavingError]) extends IndexSettingsUpdateError case object TestSettingsNotSet extends IndexSettingsUpdateError @@ -234,7 +234,7 @@ object RorInstance { sealed trait IndexSettingsInvalidationError object IndexSettingsInvalidationError { - final case class IndexSettingsSavingError(underlying: SavingSettingsError[IndexSettingsSource.SavingError]) + final case class IndexSettingsSavingError(underlying: SettingsSavingError[IndexSettingsSource.SavingError]) extends IndexSettingsInvalidationError } diff --git a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala index 9b81134346..9cb5169422 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/SettingsRelatedCreatorsAndLoaders.scala @@ -19,7 +19,7 @@ package tech.beshu.ror.boot import tech.beshu.ror.api.{MainSettingsApi, TestSettingsApi} import tech.beshu.ror.boot.engines.{MainSettingsBasedReloadableEngine, TestSettingsBasedReloadableEngine} import tech.beshu.ror.es.IndexDocumentManager -import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, LoadingRorCoreStrategySettings} +import tech.beshu.ror.settings.es.{EsConfigBasedRorSettings, RorCoreSettingsLoadingStrategy} import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser import tech.beshu.ror.settings.ror.loader.{ConfigurableRetryStrategy, ForceLoadRorSettingsFromFileLoader, RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader, StartingRorSettingsLoader} import tech.beshu.ror.settings.ror.source.{MainSettingsFileSource, MainSettingsIndexSource, TestSettingsIndexSource} @@ -38,10 +38,10 @@ object SettingsRelatedCreatorsAndLoaders { val mainSettingsIndexSource = MainSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) val mainSettingsFileSource = MainSettingsFileSource.create(settingsFile, settingsYamlParser) val testSettingsIndexSource = TestSettingsIndexSource.create(indexDocumentManager, settingsIndex, settingsYamlParser) - val startingSettingsLoader = esConfigBasedRorSettings.loadingRorCoreStrategy match { - case s@LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings => + val startingSettingsLoader = esConfigBasedRorSettings.rorCoreSettingsLoadingStrategy match { + case RorCoreSettingsLoadingStrategy.ForceLoadingFromFileSettings => new ForceLoadRorSettingsFromFileLoader(mainSettingsFileSource) - case s@LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback(retryStrategySettings, _) => + case RorCoreSettingsLoadingStrategy.LoadFromIndexWithFileFallback(retryStrategySettings, _) => new RetryableIndexSourceWithFileSourceFallbackRorSettingsLoader( mainSettingsIndexSource, new ConfigurableRetryStrategy(retryStrategySettings), diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala index d9d7ee2bc3..ec6370e186 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/MainSettingsBasedReloadableEngine.scala @@ -33,7 +33,7 @@ import tech.beshu.ror.implicits.* import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.settings.ror.MainRorSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError.SourceSpecificError import tech.beshu.ror.settings.ror.source.{IndexSettingsSource, MainSettingsIndexSource} import tech.beshu.ror.utils.ScalaOps.value diff --git a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala index 9d1f53e73f..191eacf41a 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/engines/TestSettingsBasedReloadableEngine.scala @@ -34,9 +34,9 @@ import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.settings.ror.TestRorSettings.Expiration import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.{LoadingError, SavingError} -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError.SourceSpecificError import tech.beshu.ror.settings.ror.source.{IndexSettingsSource, TestSettingsIndexSource} import tech.beshu.ror.settings.ror.{RawRorSettings, TestRorSettings} import tech.beshu.ror.utils.DurationOps.PositiveFiniteDuration @@ -192,7 +192,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest } private def saveSettingsInIndex[A](newSettings: TestRorSettings, - onFailure: SavingSettingsError[SavingError] => A): EitherT[Task, A, Unit] = { + onFailure: SettingsSavingError[SavingError] => A): EitherT[Task, A, Unit] = { EitherT(testSettingsSource.save(newSettings)) .leftMap(onFailure) } @@ -221,7 +221,7 @@ private[boot] class TestSettingsBasedReloadableEngine private(boot: ReadonlyRest EitherT(testSettingsSource.load()) .map(Some(_)) .leftFlatMap { - case LoadingSettingsError.SourceSpecificError(LoadingError.DocumentNotFound | LoadingError.IndexNotFound) => + case SettingsLoadingError.SourceSpecificError(LoadingError.DocumentNotFound | LoadingError.IndexNotFound) => EitherT.rightT(None) case error => EitherT.leftT(IndexSettingsReloadError.IndexLoadingSettingsError(error): IndexSettingsReloadError) diff --git a/core/src/main/scala/tech/beshu/ror/implicits.scala b/core/src/main/scala/tech/beshu/ror/implicits.scala index 624764e3b4..3c206c5b45 100644 --- a/core/src/main/scala/tech/beshu/ror/implicits.scala +++ b/core/src/main/scala/tech/beshu/ror/implicits.scala @@ -60,13 +60,13 @@ import tech.beshu.ror.accesscontrol.request.RequestContext import tech.beshu.ror.boot.ReadonlyRest.StartingFailure import tech.beshu.ror.providers.EnvVarProvider.EnvVarName import tech.beshu.ror.providers.PropertiesProvider.PropName -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError import tech.beshu.ror.settings.ror.RawRorSettingsYamlParser.ParsingRorSettingsError.{InvalidContent, MoreThanOneRorSection, NoRorSection} -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError import tech.beshu.ror.settings.ror.source.{FileSettingsSource, IndexSettingsSource} import tech.beshu.ror.settings.ror.{MainRorSettings, TestRorSettings} import tech.beshu.ror.utils.ScalaOps.* @@ -457,12 +457,12 @@ trait LogsShowInstances implicit val startingFailureShow: Show[StartingFailure] = Show.show(_.message) - implicit def loadingSettingsErrorShow[ERROR: Show]: Show[LoadingSettingsError[ERROR]] = Show.show { - case LoadingSettingsError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" - case LoadingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + implicit def settingsLoadingErrorShow[ERROR: Show]: Show[SettingsLoadingError[ERROR]] = Show.show { + case SettingsLoadingError.SettingsMalformed(cause) => s"ROR settings are malformed: $cause" + case SettingsLoadingError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) } - implicit def savingSettingsErrorShow[ERROR: Show]: Show[SavingSettingsError[ERROR]] = Show.show { - case SavingSettingsError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) + implicit def settingsSavingErrorShow[ERROR: Show]: Show[SettingsSavingError[ERROR]] = Show.show { + case SettingsSavingError.SourceSpecificError(error) => implicitly[Show[ERROR]].show(error) } } diff --git a/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala b/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala index f4d057d2a4..910e74ded1 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/RorProperties.scala @@ -27,8 +27,8 @@ import tech.beshu.ror.accesscontrol.domain.RorSettingsFile import tech.beshu.ror.implicits.* import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.providers.PropertiesProvider.PropName -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.CoreRefreshSettings -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.CoreRefreshSettings +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.utils.DurationOps.* import tech.beshu.ror.utils.RefinedUtils.* @@ -39,7 +39,7 @@ import scala.util.{Failure, Success, Try} object RorProperties extends Logging { - object defaults { + private object defaults { val refreshInterval: PositiveFiniteDuration = (5 second).toRefinedPositiveUnsafe val loadingDelay: NonNegativeFiniteDuration = (5 second).toRefinedNonNegativeUnsafe val loadingAttemptsCount: Int Refined NonNegative = Refined.unsafeApply(5) @@ -47,7 +47,7 @@ object RorProperties extends Logging { val rorSettingsMaxSize: Information = Megabytes(3) } - object keys { + private object keys { val rorSettingsFilePath: NonEmptyString = nes("com.readonlyrest.settings.file.path") val rorSettingsRefreshInterval: NonEmptyString = nes("com.readonlyrest.settings.refresh.interval") val startupIndexLoadingDelay: NonEmptyString = nes("com.readonlyrest.settings.loading.delay") diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala index d1a1621207..895b640e53 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/EsConfigBasedRorSettings.scala @@ -27,7 +27,7 @@ import scala.language.{implicitConversions, postfixOps} final case class EsConfigBasedRorSettings(settingsSource: RorSettingsSourcesConfig, boot: RorBootSettings, ssl: Option[RorSslSettings], - loadingRorCoreStrategy: LoadingRorCoreStrategySettings) + rorCoreSettingsLoadingStrategy: RorCoreSettingsLoadingStrategy) object EsConfigBasedRorSettings { @@ -37,7 +37,7 @@ object EsConfigBasedRorSettings { settingsSource <- EitherT(RorSettingsSourcesConfig.from(esEnv)) bootSettings <- EitherT(RorBootSettings.load(esEnv)) sslSettings <- EitherT(RorSslSettings.load(esEnv, settingsSource.settingsFile)) - loadingRorCoreStrategy <- EitherT(LoadingRorCoreStrategySettings.load(esEnv)) + loadingRorCoreStrategy <- EitherT(RorCoreSettingsLoadingStrategy.load(esEnv)) } yield EsConfigBasedRorSettings(settingsSource, bootSettings, sslSettings, loadingRorCoreStrategy) result.value } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorCoreSettingsLoadingStrategy.scala similarity index 88% rename from core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala rename to core/src/main/scala/tech/beshu/ror/settings/es/RorCoreSettingsLoadingStrategy.scala index c3c09c5c62..28dc3e8e75 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/LoadingRorCoreStrategySettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorCoreSettingsLoadingStrategy.scala @@ -25,7 +25,7 @@ import tech.beshu.ror.SystemContext import tech.beshu.ror.es.EsEnv import tech.beshu.ror.providers.PropertiesProvider import tech.beshu.ror.settings.RorProperties -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.LoadingRetryStrategySettings.{LoadingAttemptsCount, LoadingAttemptsInterval, LoadingDelay} import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.utils.DurationOps.{NonNegativeFiniteDuration, PositiveFiniteDuration, RefinedDurationOps} import tech.beshu.ror.utils.yaml.YamlKeyDecoder @@ -33,13 +33,13 @@ import tech.beshu.ror.utils.yaml.YamlKeyDecoder import scala.concurrent.duration.{DurationInt, FiniteDuration} import scala.language.{implicitConversions, postfixOps} -sealed trait LoadingRorCoreStrategySettings -object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport { +sealed trait RorCoreSettingsLoadingStrategy +object RorCoreSettingsLoadingStrategy extends YamlFileBasedSettingsLoaderSupport { - case object ForceLoadingFromFileSettings extends LoadingRorCoreStrategySettings + case object ForceLoadingFromFileSettings extends RorCoreSettingsLoadingStrategy final case class LoadFromIndexWithFileFallback(indexLoadingRetrySettings: LoadingRetryStrategySettings, coreRefreshSettings: CoreRefreshSettings) - extends LoadingRorCoreStrategySettings + extends RorCoreSettingsLoadingStrategy final case class LoadingRetryStrategySettings(attemptsInterval: LoadingAttemptsInterval, attemptsCount: LoadingAttemptsCount, @@ -73,25 +73,25 @@ object LoadingRorCoreStrategySettings extends YamlFileBasedSettingsLoaderSupport } def load(esEnv: EsEnv) - (implicit systemContext: SystemContext): Task[Either[LoadingError, LoadingRorCoreStrategySettings]] = { - implicit val decoder: Decoder[LoadingRorCoreStrategySettings] = decoders.loadRorCoreStrategyDecoder(esEnv) - loadSetting[LoadingRorCoreStrategySettings](esEnv, "ROR loading core strategy settings") + (implicit systemContext: SystemContext): Task[Either[LoadingError, RorCoreSettingsLoadingStrategy]] = { + implicit val decoder: Decoder[RorCoreSettingsLoadingStrategy] = decoders.loadRorCoreStrategyDecoder(esEnv) + loadSetting[RorCoreSettingsLoadingStrategy](esEnv, "ROR loading core strategy settings") } private object decoders { implicit def loadRorCoreStrategyDecoder(esEnv: EsEnv) - (implicit systemContext: SystemContext): Decoder[LoadingRorCoreStrategySettings] = { + (implicit systemContext: SystemContext): Decoder[RorCoreSettingsLoadingStrategy] = { YamlKeyDecoder[Boolean]( path = NonEmptyList.of("readonlyrest", "force_load_from_file"), default = false ) flatMap { case true => - Decoder.const(LoadingRorCoreStrategySettings.ForceLoadingFromFileSettings) + Decoder.const(RorCoreSettingsLoadingStrategy.ForceLoadingFromFileSettings) case false => for { loadingRetryStrategySettings <- loadLoadingRetryStrategySettings(systemContext.propertiesProvider) coreRefreshIntervalSettings <- loadCoreRefreshSettings(systemContext.propertiesProvider) - } yield LoadingRorCoreStrategySettings.LoadFromIndexWithFileFallback( + } yield RorCoreSettingsLoadingStrategy.LoadFromIndexWithFileFallback( loadingRetryStrategySettings, coreRefreshIntervalSettings ) } diff --git a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala index 86915d3817..958646a025 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/es/RorSslSettings.scala @@ -211,7 +211,7 @@ object SslSettings { fipsMode: FipsMode) extends SslSettings { - val certificateVerificationEnabled: Boolean = false + override val certificateVerificationEnabled: Boolean = false } final case class InternodeSslSettings(serverCertificateSettings: ServerCertificateSettings, diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala index b39472a053..b8434813e9 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/loader/RetryStrategy.scala @@ -22,7 +22,7 @@ import cats.implicits.toShow import monix.eval.Task import org.apache.logging.log4j.scala.Logging import tech.beshu.ror.implicits.* -import tech.beshu.ror.settings.es.LoadingRorCoreStrategySettings.LoadingRetryStrategySettings +import tech.beshu.ror.settings.es.RorCoreSettingsLoadingStrategy.LoadingRetryStrategySettings trait RetryStrategy { def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], @@ -32,12 +32,6 @@ trait RetryStrategy { EitherT(withRetry(operation.value, operationDescription)) } -object NoRetryStrategy extends RetryStrategy { - override def withRetry[ERROR: Show, RESULT](operation: Task[Either[ERROR, RESULT]], - operationDescription: String): Task[Either[ERROR, RESULT]] = - operation -} - class ConfigurableRetryStrategy(config: LoadingRetryStrategySettings) extends RetryStrategy with Logging { diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala index 8ece7c6a76..8f9405355e 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/FileSettingsSource.scala @@ -22,8 +22,8 @@ import io.circe.{Decoder, Json} import monix.eval.Task import tech.beshu.ror.settings.ror.source.FileSettingsSource.FileSettingsLoadingError import tech.beshu.ror.settings.ror.source.FileSettingsSource.LoadingError.FileNotExist -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError.SourceSpecificError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError.SourceSpecificError class FileSettingsSource[SETTINGS: Decoder](val settingsFile: File) extends ReadOnlySettingsSource[SETTINGS, FileSettingsSource.LoadingError] { @@ -44,13 +44,13 @@ class FileSettingsSource[SETTINGS: Decoder](val settingsFile: File) .subflatMap { raw => Json .fromString(raw).as[SETTINGS] - .left.map { failure => LoadingSettingsError.SettingsMalformed(failure.message) } + .left.map { failure => SettingsLoadingError.SettingsMalformed(failure.message) } } } } object FileSettingsSource { - type FileSettingsLoadingError = LoadingSettingsError[LoadingError] + type FileSettingsLoadingError = SettingsLoadingError[LoadingError] sealed trait LoadingError object LoadingError { diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala index 0613fa8f68..a3f08989e2 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/IndexSettingsSource.scala @@ -25,8 +25,8 @@ import tech.beshu.ror.es.IndexDocumentManager.CannotWriteToIndex import tech.beshu.ror.settings.ror.source.IndexSettingsSource.LoadingError.{DocumentNotFound, IndexNotFound} import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.{IndexSettingsLoadingError, IndexSettingsSavingError, LoadingError, SavingError} -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: IndexDocumentManager, val settingsIndex: IndexName.Full, @@ -40,7 +40,7 @@ class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: Ind case Right(document) => document.as[SETTINGS] .left.map { decodingFailure => - LoadingSettingsError.SettingsMalformed(decodingFailure.message) + SettingsLoadingError.SettingsMalformed(decodingFailure.message) } case Left(IndexDocumentManager.IndexNotFound) => settingsLoaderError(IndexNotFound) @@ -53,17 +53,17 @@ class IndexSettingsSource[SETTINGS: Encoder : Decoder](indexDocumentManager: Ind indexDocumentManager .saveDocumentJson(settingsIndex, documentId, settings.asJson) .map { - _.left.map { case CannotWriteToIndex => SavingSettingsError.SourceSpecificError(CannotSaveSettings) } + _.left.map { case CannotWriteToIndex => SettingsSavingError.SourceSpecificError(CannotSaveSettings) } } } private def settingsLoaderError(error: LoadingError) = - Left(LoadingSettingsError.SourceSpecificError(error)) + Left(SettingsLoadingError.SourceSpecificError(error)) } object IndexSettingsSource { - type IndexSettingsLoadingError = LoadingSettingsError[LoadingError] + type IndexSettingsLoadingError = SettingsLoadingError[LoadingError] sealed trait LoadingError object LoadingError { @@ -71,7 +71,7 @@ object IndexSettingsSource { case object DocumentNotFound extends LoadingError } - type IndexSettingsSavingError = SavingSettingsError[SavingError] + type IndexSettingsSavingError = SettingsSavingError[SavingError] sealed trait SavingError object SavingError { diff --git a/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala b/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala index 3d10408be1..3618a87e04 100644 --- a/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala +++ b/core/src/main/scala/tech/beshu/ror/settings/ror/source/SettingsSource.scala @@ -18,30 +18,30 @@ package tech.beshu.ror.settings.ror.source import io.circe.{Decoder, Encoder} import monix.eval.Task -import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.LoadingSettingsError -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadOnlySettingsSource.SettingsLoadingError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError sealed trait SettingsSource[SETTINGS] trait ReadOnlySettingsSource[SETTINGS: Decoder, ERROR] extends SettingsSource[SETTINGS] { - def load(): Task[Either[LoadingSettingsError[ERROR], SETTINGS]] + def load(): Task[Either[SettingsLoadingError[ERROR], SETTINGS]] } object ReadOnlySettingsSource { - sealed trait LoadingSettingsError[+ERROR] - object LoadingSettingsError { - final case class SettingsMalformed(cause: String) extends LoadingSettingsError[Nothing] - final case class SourceSpecificError[ERROR](error: ERROR) extends LoadingSettingsError[ERROR] + sealed trait SettingsLoadingError[+ERROR] + object SettingsLoadingError { + final case class SettingsMalformed(cause: String) extends SettingsLoadingError[Nothing] + final case class SourceSpecificError[ERROR](error: ERROR) extends SettingsLoadingError[ERROR] } } trait ReadWriteSettingsSource[SETTINGS: Encoder : Decoder, READ_SPECIFIC_ERROR, WRITE_SPECIFIC_ERROR] extends ReadOnlySettingsSource[SETTINGS, READ_SPECIFIC_ERROR] { - def save(settings: SETTINGS): Task[Either[SavingSettingsError[WRITE_SPECIFIC_ERROR], Unit]] + def save(settings: SETTINGS): Task[Either[SettingsSavingError[WRITE_SPECIFIC_ERROR], Unit]] } object ReadWriteSettingsSource { - sealed trait SavingSettingsError[+ERROR] - object SavingSettingsError { - final case class SourceSpecificError[ERROR](error: ERROR) extends SavingSettingsError[ERROR] + sealed trait SettingsSavingError[+ERROR] + object SettingsSavingError { + final case class SourceSpecificError[ERROR](error: ERROR) extends SettingsSavingError[ERROR] } } \ No newline at end of file diff --git a/core/src/test/resources/boot_tests/bad_index_config/elasticsearch.yml b/core/src/test/resources/boot_tests/bad_index_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/bad_index_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/bad_index_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml b/core/src/test/resources/boot_tests/bad_index_settings/readonlyrest_index.yml similarity index 100% rename from core/src/test/resources/boot_tests/bad_index_config/readonlyrest_index.yml rename to core/src/test/resources/boot_tests/bad_index_settings/readonlyrest_index.yml diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/elasticsearch.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml b/core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/es_api_ssl_settings_in_readonlyrest_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/forced_file_loading_bad_config/elasticsearch.yml b/core/src/test/resources/boot_tests/forced_file_loading_bad_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/forced_file_loading_bad_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/forced_file_loading_bad_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_bad_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/forced_file_loading_bad_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/forced_file_loading_bad_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/elasticsearch.yml b/core/src/test/resources/boot_tests/forced_file_loading_malformed_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/forced_file_loading_malformed_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/forced_file_loading_malformed_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml b/core/src/test/resources/boot_tests/forced_file_loading_malformed_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/forced_file_loading_malformed_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/forced_file_loading_malformed_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config/custom_index_defined/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings/custom_index_defined/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config/custom_index_defined/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings/custom_index_defined/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings/custom_index_defined/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config/custom_index_defined/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings/custom_index_defined/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/config_reloading/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings/no_index_defined/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/config_reloading/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings/no_index_defined/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings/no_index_defined/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config/no_index_defined/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings/no_index_defined/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config/no_index_defined/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings_available_file_settings_not_provided/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config/no_index_defined/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings_available_file_settings_not_provided/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml b/core/src/test/resources/boot_tests/index_settings_available_file_settings_not_provided/readonlyrest_index.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/readonlyrest_index.yml rename to core/src/test/resources/boot_tests/index_settings_available_file_settings_not_provided/readonlyrest_index.yml diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_available_file_config_not_provided/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml b/core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/readonlyrest_index.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_available_file_config_provided/readonlyrest_index.yml rename to core/src/test/resources/boot_tests/index_settings_available_file_settings_provided/readonlyrest_index.yml diff --git a/core/src/test/resources/boot_tests/index_config_available_file_config_provided/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings_not_exists_bad_file_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_available_file_config_provided/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings_not_exists_bad_file_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings_not_exists_bad_file_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings_not_exists_bad_file_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings_not_exists_malformed_file_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings_not_exists_malformed_file_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings_not_exists_malformed_file_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_not_exists_malformed_file_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings_not_exists_malformed_file_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/elasticsearch.yml b/core/src/test/resources/boot_tests/index_settings_reloading/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_not_exists_bad_file_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/index_settings_reloading/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings_reloading/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_reloading/readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings_reloading/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml b/core/src/test/resources/boot_tests/index_settings_reloading/updated_readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_reloading/updated_readonlyrest.yml rename to core/src/test/resources/boot_tests/index_settings_reloading/updated_readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/elasticsearch.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml b/core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/internode_ssl_settings_in_readonlyrest_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/index_config_reloading/elasticsearch.yml b/core/src/test/resources/boot_tests/malformed_index_settings/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/index_config_reloading/elasticsearch.yml rename to core/src/test/resources/boot_tests/malformed_index_settings/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml b/core/src/test/resources/boot_tests/malformed_index_settings/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/malformed_index_config/readonlyrest.yml rename to core/src/test/resources/boot_tests/malformed_index_settings/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml b/core/src/test/resources/boot_tests/malformed_index_settings/readonlyrest_index.yml similarity index 100% rename from core/src/test/resources/boot_tests/malformed_index_config/readonlyrest_index.yml rename to core/src/test/resources/boot_tests/malformed_index_settings/readonlyrest_index.yml diff --git a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/elasticsearch.yml b/core/src/test/resources/boot_tests/no_index_settings_file_settings_provided/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/no_index_config_file_config_provided/elasticsearch.yml rename to core/src/test/resources/boot_tests/no_index_settings_file_settings_provided/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml b/core/src/test/resources/boot_tests/no_index_settings_file_settings_provided/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/no_index_config_file_config_provided/readonlyrest.yml rename to core/src/test/resources/boot_tests/no_index_settings_file_settings_provided/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/malformed_index_config/elasticsearch.yml b/core/src/test/resources/boot_tests/settings_reloading/elasticsearch.yml similarity index 100% rename from core/src/test/resources/boot_tests/malformed_index_config/elasticsearch.yml rename to core/src/test/resources/boot_tests/settings_reloading/elasticsearch.yml diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml b/core/src/test/resources/boot_tests/settings_reloading/readonlyrest.yml similarity index 100% rename from core/src/test/resources/boot_tests/config_reloading/readonlyrest.yml rename to core/src/test/resources/boot_tests/settings_reloading/readonlyrest.yml diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml b/core/src/test/resources/boot_tests/settings_reloading/readonlyrest_first.yml similarity index 100% rename from core/src/test/resources/boot_tests/config_reloading/readonlyrest_first.yml rename to core/src/test/resources/boot_tests/settings_reloading/readonlyrest_first.yml diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml b/core/src/test/resources/boot_tests/settings_reloading/readonlyrest_initial.yml similarity index 100% rename from core/src/test/resources/boot_tests/config_reloading/readonlyrest_initial.yml rename to core/src/test/resources/boot_tests/settings_reloading/readonlyrest_initial.yml diff --git a/core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml b/core/src/test/resources/boot_tests/settings_reloading/readonlyrest_second.yml similarity index 100% rename from core/src/test/resources/boot_tests/config_reloading/readonlyrest_second.yml rename to core/src/test/resources/boot_tests/settings_reloading/readonlyrest_second.yml diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala index 3c4442886f..ee07831408 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/IndexSettingsRelatedRorCoreTest.scala @@ -73,7 +73,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/") + createEsConfigBasedRorSettings("/boot_tests/index_settings//no_index_defined/") ) } { _ => // nothing - just should start @@ -88,7 +88,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/"), + createEsConfigBasedRorSettings("/boot_tests/index_settings//no_index_defined/"), (indexDocumentManager, coreFactory) ) } { case (rorInstance, (indexDocumentManager, coreFactory)) => @@ -113,7 +113,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/no_index_defined/"), + createEsConfigBasedRorSettings("/boot_tests/index_settings//no_index_defined/"), (indexDocumentManager, coreFactory) ) } { case (rorInstance, (indexDocumentManager, coreFactory)) => @@ -140,7 +140,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/") + createEsConfigBasedRorSettings("/boot_tests/index_settings//custom_index_defined/") ) } { _ => // nothing - just should start @@ -155,7 +155,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/"), + createEsConfigBasedRorSettings("/boot_tests/index_settings//custom_index_defined/"), (indexDocumentManager, coreFactory) ) } { case (rorInstance, (indexDocumentManager, coreFactory)) => @@ -180,7 +180,7 @@ class IndexSettingsRelatedRorCoreTest extends AnyWordSpec ( createReadonlyRestBoot(coreFactory, indexDocumentManager), - createEsConfigBasedRorSettings("/boot_tests/index_config/custom_index_defined/"), + createEsConfigBasedRorSettings("/boot_tests/index_settings//custom_index_defined/"), (indexDocumentManager, coreFactory) ) } { case (rorInstance, (indexDocumentManager, coreFactory)) => diff --git a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala index 41292fa7e3..ced3cb4b90 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/boot/ReadonlyRestStartingTests.scala @@ -59,7 +59,7 @@ import tech.beshu.ror.settings.es.EsConfigBasedRorSettings import tech.beshu.ror.settings.es.YamlFileBasedSettingsLoader.LoadingError import tech.beshu.ror.settings.ror.RawRorSettings import tech.beshu.ror.settings.ror.source.IndexSettingsSource.SavingError.CannotSaveSettings -import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SavingSettingsError +import tech.beshu.ror.settings.ror.source.ReadWriteSettingsSource.SettingsSavingError import tech.beshu.ror.syntax.* import tech.beshu.ror.unit.utils.WithReadonlyrestBootSupport import tech.beshu.ror.utils.DurationOps.* @@ -88,7 +88,7 @@ class ReadonlyRestStartingTests "support the main engine" should { "be loaded from file" when { "index is not available but file settings is provided" in withReadonlyRest({ - val resourcePath = "/boot_tests/no_index_config_file_config_provided" + val resourcePath = "/boot_tests/no_index_settings_file_settings_provided" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) @@ -120,7 +120,7 @@ class ReadonlyRestStartingTests } "be loaded from index" when { "index is available and file settings is provided" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) @@ -137,7 +137,7 @@ class ReadonlyRestStartingTests acl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] } "index is available and file settings is not provided" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettings(mockedIndexDocumentManager, resourcesPath + indexSettingsFile) @@ -156,7 +156,7 @@ class ReadonlyRestStartingTests } "be able to be reloaded" when { "new settings are different than old one" in withReadonlyRest({ - val resourcesPath = "/boot_tests/config_reloading/" + val resourcesPath = "/boot_tests/settings_reloading/" val initialIndexSettingsFile = "readonlyrest_initial.yml" val newIndexSettingsFile = "readonlyrest_first.yml" @@ -180,14 +180,14 @@ class ReadonlyRestStartingTests mainEngine.core.accessControl.asInstanceOf[AccessControlListLoggingDecorator].underlying shouldBe a[EnabledAcl] val reload1Result = rorInstance - .forceReloadAndSave(rorSettingsFromResource("/boot_tests/config_reloading/readonlyrest_first.yml"))(newRequestId()) + .forceReloadAndSave(rorSettingsFromResource("/boot_tests/settings_reloading/readonlyrest_first.yml"))(newRequestId()) .runSyncUnsafe() reload1Result should be(Right(())) assert(mainEngine != rorInstance.engines.value.mainEngine, "Engine was not reloaded") } "two parallel force reloads are invoked" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/config_reloading/" + val resourcesPath = "/boot_tests/settings_reloading/" val initialIndexSettingsFile = "readonlyrest_initial.yml" val firstNewIndexSettingsFile = "readonlyrest_first.yml" val secondNewIndexSettingsFile = "readonlyrest_second.yml" @@ -219,7 +219,7 @@ class ReadonlyRestStartingTests mockedIndexDocumentManager ) }) { case (rorInstance, mockedIndexDocumentManager) => - val resourcesPath = "/boot_tests/config_reloading/" + val resourcesPath = "/boot_tests/settings_reloading/" val firstNewIndexSettingsFile = "readonlyrest_first.yml" val secondNewIndexSettingsFile = "readonlyrest_second.yml" @@ -249,7 +249,7 @@ class ReadonlyRestStartingTests } } "be reloaded if index settings change" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_reloading/" + val resourcesPath = "/boot_tests/index_settings_reloading/" val originIndexSettingsFile = "readonlyrest.yml" val updatedIndexSettingsFile = "updated_readonlyrest.yml" @@ -285,7 +285,7 @@ class ReadonlyRestStartingTests } "failed to load" when { "force load from file is set and settings file is malformed yaml" in { - val resourcesPath = "/boot_tests/forced_file_loading_malformed_config/" + val resourcesPath = "/boot_tests/forced_file_loading_malformed_settings/" implicit val systemContext: SystemContext = createSystemContext() val result = createEsConfigBasedRorSettings(resourcesPath) @@ -294,7 +294,7 @@ class ReadonlyRestStartingTests } } "force load from file is set and core cannot be loaded" in { - val resourcesPath = "/boot_tests/forced_file_loading_bad_config/" + val resourcesPath = "/boot_tests/forced_file_loading_bad_settings/" val coreFactory = mockFailedCoreFactory(mock[CoreFactory], resourcesPath + "readonlyrest.yml") implicit val systemContext: SystemContext = createSystemContext() @@ -308,7 +308,7 @@ class ReadonlyRestStartingTests } } "index settings don't exist and settings file is malformed yaml" in { - val resourcesPath = "/boot_tests/index_config_not_exists_malformed_file_config/" + val resourcesPath = "/boot_tests/index_settings_not_exists_malformed_file_settings/" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = IndexNotFound) @@ -326,7 +326,7 @@ class ReadonlyRestStartingTests } } "index settings don't exist and core cannot be loaded" in { - val resourcePath = "/boot_tests/index_config_not_exists_bad_file_config/" + val resourcePath = "/boot_tests/index_settings_not_exists_bad_file_settings/" val mockedIndexDocumentManager = mock[IndexDocumentManager] mockGettingMainSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) mockGettingTestSettingsReturnsError(mockedIndexDocumentManager, error = DocumentNotFound) @@ -344,7 +344,7 @@ class ReadonlyRestStartingTests } } "index settings are malformed" in { - val resourcesPath = "/boot_tests/malformed_index_config/" + val resourcesPath = "/boot_tests/malformed_index_settings/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -365,7 +365,7 @@ class ReadonlyRestStartingTests } } "index settings cannot be loaded" in { - val resourcesPath = "/boot_tests/bad_index_config/" + val resourcesPath = "/boot_tests/bad_index_settings/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -412,7 +412,7 @@ class ReadonlyRestStartingTests "support the test engine" which { "can be initialized" when { "there is no settings in index" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -436,7 +436,7 @@ class ReadonlyRestStartingTests "there is some settings stored in index" should { "load test engine as active" when { "settings are still valid" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -503,7 +503,7 @@ class ReadonlyRestStartingTests } "load test engine as invalidated" when { "the expiration timestamp exceeded" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().minusSeconds(100) @@ -543,7 +543,7 @@ class ReadonlyRestStartingTests } "index is not accessible" should { "fallback to not configured" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -566,7 +566,7 @@ class ReadonlyRestStartingTests } "settings structure is not valid" should { "fallback to not configured" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().minusSeconds(100) @@ -600,7 +600,7 @@ class ReadonlyRestStartingTests } "settings structure is valid, rule is malformed and cannot start engine" should { "fallback to invalidated settings" in withReadonlyRest({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -639,7 +639,7 @@ class ReadonlyRestStartingTests } "can be loaded on demand" when { "there is no previous engine" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -691,7 +691,7 @@ class ReadonlyRestStartingTests } "there is previous engine" when { "same settings and ttl" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -760,7 +760,7 @@ class ReadonlyRestStartingTests testEngine2Expiration.isAfter(testEngine1Expiration) should be(true) } "different ttl" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -843,7 +843,7 @@ class ReadonlyRestStartingTests } } "different settings is being loaded" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -929,7 +929,7 @@ class ReadonlyRestStartingTests } "can be reloaded if index settings changes" when { "new settings and expiration time has not exceeded" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -978,7 +978,7 @@ class ReadonlyRestStartingTests ) } "same settings and the ttl has changed" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1042,7 +1042,7 @@ class ReadonlyRestStartingTests ) } "same settings and the expiration time has changed" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1108,7 +1108,7 @@ class ReadonlyRestStartingTests ) } "new settings and has already expired" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1174,7 +1174,7 @@ class ReadonlyRestStartingTests } "should be automatically unloaded" when { "engine ttl has reached" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -1227,7 +1227,7 @@ class ReadonlyRestStartingTests } } "can be invalidated by user" in withReadonlyRestExt({ - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" val mockedIndexDocumentManager = mock[IndexDocumentManager] @@ -1295,7 +1295,7 @@ class ReadonlyRestStartingTests "should return error for invalidation" when { "cannot save invalidation timestamp in index" in withReadonlyRestExt( { - val resourcesPath = "/boot_tests/index_config_available_file_config_not_provided/" + val resourcesPath = "/boot_tests/index_settings_available_file_settings_not_provided/" val indexSettingsFile = "readonlyrest_index.yml" lazy val expirationTimestamp = testClock.instant().plusSeconds(100) @@ -1352,7 +1352,7 @@ class ReadonlyRestStartingTests .returns(Task.now(Left(CannotWriteToIndex))) rorInstance.invalidateTestSettingsEngine()(newRequestId()).runSyncUnsafe() should be( - Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SavingSettingsError.SourceSpecificError(CannotSaveSettings))) + Left(IndexSettingsInvalidationError.IndexSettingsSavingError(SettingsSavingError.SourceSpecificError(CannotSaveSettings))) ) rorInstance.engines.value.impersonatorsEngine should be(Option.empty) diff --git a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala index 79089e646a..73f5ab8fe7 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/settings/es/RorSslSettingsTest.scala @@ -86,7 +86,7 @@ class RorSslSettingsTest } "be loaded from readonlyrest config file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_readonlyrest_config") + val ssl = forceLoadRorSslSettings("/boot_tests/es_api_ssl_settings_in_readonlyrest_settings") inside(ssl.externalSsl) { case Some(ExternalSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") @@ -175,7 +175,7 @@ class RorSslSettingsTest } "be loaded from readonlyrest settings file" when { "elasticsearch config file doesn't contain ROR ssl section" in { - val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_readonlyrest_config") + val ssl = forceLoadRorSslSettings("/boot_tests/internode_ssl_settings_in_readonlyrest_settings") inside(ssl.internodeSsl) { case Some(InternodeSslSettings(KeystoreBasedSettings(keystoreFile, Some(keystorePassword), None, Some(keyPass)), Some(ClientCertificateSettings.TruststoreBasedSettings(truststoreFile, Some(truststorePassword))), allowedProtocols, allowedCiphers, clientAuthenticationEnabled, certificateVerificationEnabled, hostnameVerificationEnabled, FipsMode.NonFips)) => keystoreFile.value.name should be("ror-keystore.jks") diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index 61ce37115c..6b3ba82e6a 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -41,7 +41,7 @@ class RorStartingResponseCodeSuite extends AnyWordSpec with ESVersionSupportForA implicit val scheduler: Scheduler = Scheduler.computation(10) - private val validRorConfigFile = "/ror_starting_response_code/malformed_readonlyrest.yml" + private val validRorSettingsFile = "/ror_starting_response_code/malformed_readonlyrest.yml" private val notStartedResponseCodeKey = "readonlyrest.not_started_response_code" @@ -66,7 +66,7 @@ class RorStartingResponseCodeSuite extends AnyWordSpec with ESVersionSupportForA private def withTestEsContainerManager(additionalEsYamlEntries: Map[String, String]) (testCode: TestEsContainerManager => Task[Unit]): Unit = { val esContainer = new TestEsContainerManager( - rorConfigFile = validRorConfigFile, + rorSettingsFile = validRorSettingsFile, additionalEsYamlEntries = additionalEsYamlEntries ) esContainer.start().runSyncUnsafe(5 minutes) @@ -113,7 +113,7 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { private val uniqueClusterId: AtomicInt = AtomicInt(1) - final class TestEsContainerManager(rorConfigFile: String, + final class TestEsContainerManager(rorSettingsFile: String, additionalEsYamlEntries: Map[String, String]) extends EsContainerCreator { private val esContainer = createEsContainer @@ -143,7 +143,7 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { clusterName = clusterName, securityType = SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( - rorSettingsFileName = rorConfigFile, + rorSettingsFileName = rorSettingsFile, rorInIndexSettingsLoadingDelay = 5 seconds ) ), diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala index 0908db6cc8..3e93efd8b7 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/LocalClusterAuditingToolsSuite.scala @@ -48,7 +48,7 @@ class LocalClusterAuditingToolsSuite override lazy val destNodesClientProviders: NonEmptyList[ClientProvider] = NonEmptyList.of(this) - override def baseRorConfig: String = resolvedRorSettingsFile.contentAsString + override def baseRorSettingsYaml: String = resolvedRorSettingsFile.contentAsString override protected def baseAuditDataStreamName: Option[String] = Option.when(Version.greaterOrEqualThan(esVersionUsed, 7, 9, 0))("audit_data_stream") @@ -279,11 +279,11 @@ class LocalClusterAuditingToolsSuite updateRorSettings(Map(originalString -> newString)) private def updateRorSettings(replacements: Map[String, String]): Unit = { - val initialConfig = getResourceContent(rorSettingsFileName) - val modifiedConfig = replacements.foldLeft(initialConfig) { case (soFar, (originalString, newString)) => + val initialSettings = getResourceContent(rorSettingsFileName) + val modifiedSettings = replacements.foldLeft(initialSettings) { case (soFar, (originalString, newString)) => soFar.replace(originalString, newString) } - rorApiManager.updateRorInIndexSettings(modifiedConfig).forceOKStatusOrSettingsAlreadyLoaded() + rorApiManager.updateRorInIndexSettings(modifiedSettings).forceOKStatusOrSettingsAlreadyLoaded() rorApiManager.reloadRorSettings().force() } } diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala index 1a55125927..783b61de00 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/audit/RemoteClusterAuditingToolsSuite.scala @@ -89,7 +89,7 @@ class RemoteClusterAuditingToolsSuite override lazy val destNodesClientProviders: NonEmptyList[ClientProvider] = NonEmptyList.fromListUnsafe(auditEsContainers) - override protected def baseRorConfig: String = resolvedRorSettingsFile.contentAsString + override protected def baseRorSettingsYaml: String = resolvedRorSettingsFile.contentAsString override protected def baseAuditDataStreamName: Option[String] = Option.when(isDataStreamSupported)("audit_data_stream") @@ -107,7 +107,7 @@ class RemoteClusterAuditingToolsSuite // This test suite does not execute on Windows: there is currently no Windows version of ToxiproxyContainer ignoreOnWindows { "Should report audit events in round-robin mode, even when some nodes are unreachable" in { - rorApiManager.updateRorInIndexSettings(baseRorConfig).forceOKStatusOrSettingsAlreadyLoaded() + rorApiManager.updateRorInIndexSettings(baseRorSettingsYaml).forceOKStatusOrSettingsAlreadyLoaded() val auditNode1 = proxiedContainers(0) val auditNode2 = proxiedContainers(1) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala index 267f0fdfaf..9199532e93 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAuditingToolsSuite.scala @@ -51,7 +51,7 @@ trait BaseAuditingToolsSuite protected def assertForEveryAuditEntry(entry: JSON): Unit - protected def baseRorConfig: String + protected def baseRorSettingsYaml: String protected def baseAuditDataStreamName: Option[String] @@ -375,7 +375,7 @@ trait BaseAuditingToolsSuite disableAudit() val newIndex = s"audit-index-${UUID.randomUUID().toString}" - rorApiManager.updateRorInIndexSettings(rorConfigWithIndexAudit(newIndex)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithIndexAudit(newIndex)).forceOkStatus() val adminAuditManager = new AuditIndexManager(destNodeClientProvider.adminClient, esVersionUsed, newIndex) auditEventAssertion(adminAuditManager) @@ -392,7 +392,7 @@ trait BaseAuditingToolsSuite assertDataStreamNotExists(newDataStream) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { val response = dataStreamManager.getAllDataStreams() @@ -427,7 +427,7 @@ trait BaseAuditingToolsSuite val indexLifecycleManager = new IndexLifecycleManager(destNodeClientProvider.adminClient, esVersionUsed) indexLifecycleManager.putPolicyAndWaitForIndexing(id = s"$newDataStream-lifecycle-policy", policy) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -462,7 +462,7 @@ trait BaseAuditingToolsSuite val templateManager = new ComponentTemplateManager(destNodeClientProvider.adminClient, esVersionUsed) templateManager.putTemplateAndWaitForIndexing(templateName = s"$newDataStream-mappings", body = template) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -490,7 +490,7 @@ trait BaseAuditingToolsSuite val templateManager = new ComponentTemplateManager(destNodeClientProvider.adminClient, esVersionUsed) templateManager.putTemplateAndWaitForIndexing(templateName = s"$newDataStream-settings", body = template) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -519,7 +519,7 @@ trait BaseAuditingToolsSuite ) ) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(newDataStream)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(newDataStream)).forceOkStatus() eventually { assertDataStreamExists(newDataStream) @@ -536,7 +536,7 @@ trait BaseAuditingToolsSuite createAuditDataStream(dataStreamName) - rorApiManager.updateRorInIndexSettings(rorConfigWithDataStreamAudit(dataStreamName)).forceOkStatus() + rorApiManager.updateRorInIndexSettings(rorSettingsWithDataStreamAudit(dataStreamName)).forceOkStatus() val adminAuditManager = new AuditIndexManager(destNodeClientProvider.adminClient, esVersionUsed, dataStreamName) auditEventAssertion(adminAuditManager) @@ -554,11 +554,11 @@ trait BaseAuditingToolsSuite } private def disableAudit(): Unit = { - val initialConfig = getResourceContent("/ror_audit/disabled_auditing_tools/readonlyrest.yml") - rorApiManager.updateRorInIndexSettings(initialConfig).forceOKStatusOrSettingsAlreadyLoaded() + val initialSettings = getResourceContent("/ror_audit/disabled_auditing_tools/readonlyrest.yml") + rorApiManager.updateRorInIndexSettings(initialSettings).forceOKStatusOrSettingsAlreadyLoaded() } - private def auditEventAssertion(adminAuditManager: AuditIndexManager) = { + private def auditEventAssertion(adminAuditManager: AuditIndexManager): Unit = { val indexManager = new IndexManager(basicAuthClient("username", "dev"), esVersionUsed) val indexResponse = indexManager.getIndex("twitter") indexResponse should have statusCode 200 @@ -574,15 +574,15 @@ trait BaseAuditingToolsSuite } } - private def rorConfigWithIndexAudit(indexName: String) = { - baseRorConfig.replace( + private def rorSettingsWithIndexAudit(indexName: String) = { + baseRorSettingsYaml.replace( baseAuditIndexName, indexName ) } - private def rorConfigWithDataStreamAudit(dataStreamName: String) = { - baseRorConfig.replace( + private def rorSettingsWithDataStreamAudit(dataStreamName: String) = { + baseRorSettingsYaml.replace( baseAuditDataStreamName.getOrElse(throw new IllegalStateException("Data stream name should be set for Data Stream audit test")), dataStreamName ) From 22f2052829ed5871091de5730a9e2bf66d35c736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 15:18:33 +0100 Subject: [PATCH 077/103] fix --- .../tech/beshu/ror/es/services/EsIndexDocumentManager.scala | 1 + .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- .../tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala | 5 ++++- .../beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala | 5 +++-- 67 files changed, 232 insertions(+), 99 deletions(-) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala b/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala index e7f5ac4866..9b4400d45e 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/services/EsIndexDocumentManager.scala @@ -92,6 +92,7 @@ class EsIndexDocumentManager(client: NodeClient, client .prepareIndex() .setIndex(index.name.value) + .setType("settings") .setId(id) .setSource(document.noSpaces, XContentType.JSON) .setRefreshPolicy(RefreshPolicy.WAIT_UNTIL) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 60e4b0b852..4fecea0cd1 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.HttpServerTransport import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -39,7 +40,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es67x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 942c9d37cd..bae2f793b0 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -39,7 +40,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es70x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d30183cb08..7c3b1fda94 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es710x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d30183cb08..7c3b1fda94 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es711x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d30183cb08..7c3b1fda94 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es714x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index e9130b487e..58d8c8c639 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es716x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 991356d628..1af576d24f 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es717x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 942c9d37cd..bae2f793b0 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -39,7 +40,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es72x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 942c9d37cd..bae2f793b0 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -39,7 +40,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es73x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 942c9d37cd..bae2f793b0 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -39,7 +40,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es74x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 6b54f75c23..606c0f4c18 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -40,7 +41,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es77x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 6b54f75c23..606c0f4c18 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.http.netty4.Netty4HttpServerTransport import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -40,7 +41,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 470f7f2a18..a4fec091cb 100644 --- a/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es78x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -46,8 +47,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index d30183cb08..7c3b1fda94 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.http.{HttpChannel, HttpServerTransport} import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.SharedGroupFactory import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 2d49fb875f..6919f5755d 100644 --- a/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es79x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.SharedGroupFactory import org.elasticsearch.transport.netty4.Netty4Transport import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 675646d3ee..c40f2af9e6 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es80x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 36250d24e7..ef14b6eb89 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es810x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es811x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es812x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es813x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es814x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es815x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 33abeef01f..46d402b70a 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -43,7 +44,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es816x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 33abeef01f..46d402b70a 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -43,7 +44,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es818x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 675646d3ee..c40f2af9e6 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es81x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 675646d3ee..c40f2af9e6 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es82x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index ce726c249b..31767410bc 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -27,6 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -40,7 +41,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es83x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f1afbea188..b4eb8b51bb 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es84x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index f1afbea188..b4eb8b51bb 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.SharedGroupFactory import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 16a31fa908..e78670311e 100644 --- a/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es85x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -30,6 +30,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -47,8 +48,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, Version.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode): ChannelHandler = new ClientChannelInitializer { override def initChannel(ch: Channel): Unit = { diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b80f3b9150..0851dcb123 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cbbed3e208..8562edfc25 100644 --- a/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es87x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 4992b28bfd..473df8e3cb 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index cbbed3e208..8562edfc25 100644 --- a/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es88x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.CURRENT, threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 36250d24e7..ef14b6eb89 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.tracing.Tracer import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es89x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 33abeef01f..46d402b70a 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -29,6 +29,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -43,7 +44,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es90x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index 7fc953e792..81b7891185 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, tracer, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es91x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { diff --git a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala index b98eed4c2f..9180fa06e7 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4HttpServerTransport.scala @@ -28,6 +28,7 @@ import org.elasticsearch.threadpool.ThreadPool import org.elasticsearch.transport.netty4.{SharedGroupFactory, TLSConfig} import org.elasticsearch.xcontent.NamedXContentRegistry import tech.beshu.ror.settings.es.SslSettings.ExternalSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper class SSLNetty4HttpServerTransport(settings: Settings, @@ -42,7 +43,9 @@ class SSLNetty4HttpServerTransport(settings: Settings, extends Netty4HttpServerTransport(settings, networkService, threadPool, xContentRegistry, dispatcher, clusterSettings, sharedGroupFactory, telemetryProvider, TLSConfig.noTLS(), null, null) with Logging { - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + private val serverSslContext = doPrivileged { + SSLCertHelper.prepareServerSSLContext(ssl, ssl.clientAuthenticationEnabled) + } override def configureServerChannelHandler = new SSLHandler(this) diff --git a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala index 58d76ddebb..88b9d3c808 100644 --- a/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala +++ b/es92x/src/main/scala/tech/beshu/ror/es/ssl/SSLNetty4InternodeServerTransport.scala @@ -31,6 +31,7 @@ import org.elasticsearch.transport.ConnectionProfile import org.elasticsearch.transport.netty4.{Netty4Transport, SharedGroupFactory} import tech.beshu.ror.settings.es.RorSslSettings.IsSslFipsCompliant import tech.beshu.ror.settings.es.SslSettings.InternodeSslSettings +import tech.beshu.ror.utils.AccessControllerHelper.doPrivileged import tech.beshu.ror.utils.SSLCertHelper import tech.beshu.ror.utils.SSLCertHelper.HostAndPort @@ -48,8 +49,8 @@ class SSLNetty4InternodeServerTransport(settings: Settings, extends Netty4Transport(settings, TransportVersion.current(), threadPool, networkService, pageCacheRecycler, namedWriteableRegistry, circuitBreakerService, sharedGroupFactory) with Logging { - private val clientSslContext = SSLCertHelper.prepareClientSSLContext(ssl) - private val serverSslContext = SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) + private val clientSslContext = doPrivileged { SSLCertHelper.prepareClientSSLContext(ssl) } + private val serverSslContext = doPrivileged { SSLCertHelper.prepareServerSSLContext(ssl, clientAuthenticationEnabled = false) } override def getClientChannelInitializer(node: DiscoveryNode, connectionProfile: ConnectionProfile): ChannelHandler = new ClientChannelInitializer { From 929e80d83615da0b31c5a9fd3b8f91a96845560d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 20:58:45 +0100 Subject: [PATCH 078/103] fix --- .../ror/integration/suites/FipsSslSuite.scala | 2 +- .../suites/RorStartingResponseCodeSuite.scala | 8 ++++---- .../ElasticsearchNodeWaitingStrategy.scala | 3 ++- .../ror/utils/containers/EsContainer.scala | 20 ++++++++++++++++--- .../utils/containers/OpenLdapContainer.scala | 17 ++++++++++------ .../windows/WindowsEsPortProvider.scala | 1 + 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala index adac2742ea..2d278ab76e 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/FipsSslSuite.scala @@ -26,8 +26,8 @@ import tech.beshu.ror.utils.containers.SecurityType.RorSecurity import tech.beshu.ror.utils.containers.images.ReadonlyRestPlugin.Config.{Attributes, InternodeSsl, RestSsl} import tech.beshu.ror.utils.containers.images.domain.{Enabled, SourceFile} import tech.beshu.ror.utils.elasticsearch.CatManager +import tech.beshu.ror.utils.misc.CustomScalaTestMatchers import tech.beshu.ror.utils.misc.OsUtils.ignoreOnWindows -import tech.beshu.ror.utils.misc.{CustomScalaTestMatchers, OsUtils} class FipsSslSuite extends AnyWordSpec diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index 6b3ba82e6a..bf5e3bf329 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -46,7 +46,7 @@ class RorStartingResponseCodeSuite extends AnyWordSpec with ESVersionSupportForA private val notStartedResponseCodeKey = "readonlyrest.not_started_response_code" "ES" when { - "ROR does not started yet" should { + "ROR is not started yet" should { "return not started response with http code 403" when { "403 configured" in withTestEsContainerManager(Map(notStartedResponseCodeKey -> "403")) { esContainer => testRorStartup(usingManager = esContainer, expectedResponseCode = 403) @@ -135,12 +135,12 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { } private def createEsContainer: EsContainer = { - val clusterName = s"ROR_${uniqueClusterId.getAndIncrement()}" - val nodeName = s"${clusterName}_1" + val clusterName = s"testEsCluster_${uniqueClusterId.getAndIncrement()}" + val nodeName = clusterName create( nodeSettings = EsNodeSettings( - nodeName = nodeName, clusterName = clusterName, + nodeName = nodeName, securityType = SecurityType.RorWithXpackSecurity( ReadonlyRestWithEnabledXpackSecurityPlugin.Config.Attributes.default.copy( rorSettingsFileName = rorSettingsFile, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala index 0710dc1898..5d110aad15 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala @@ -27,6 +27,7 @@ import tech.beshu.ror.utils.misc.{EsStartupChecker, Version} import scala.util.Try class ElasticsearchNodeWaitingStrategy(esVersion: String, + esPort: Int, containerName: String, restClient: Coeval[RestClient], initializer: ElasticsearchNodeDataInitializer, @@ -76,7 +77,7 @@ class ElasticsearchNodeWaitingStrategy(esVersion: String, private def waitForRestEsApi() = { val esRestApiWaitStrategy = new HttpWaitStrategy() .usingTls().allowInsecure() - .forPort(9200) + .forPort(esPort) .forPath("/") .forStatusCodeMatching(_ => true) Try(esRestApiWaitStrategy.waitUntilReady(waitStrategyTarget)).isSuccess diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala index 4987ba5455..61ddc81718 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/EsContainer.scala @@ -29,7 +29,7 @@ import tech.beshu.ror.utils.containers.EsContainer.{Credentials, EsContainerImpl import tech.beshu.ror.utils.containers.images.{DockerImageCreator, Elasticsearch} import tech.beshu.ror.utils.containers.logs.CompositeLogConsumer import tech.beshu.ror.utils.containers.providers.ClientProvider -import tech.beshu.ror.utils.containers.windows.WindowsPseudoEsContainer +import tech.beshu.ror.utils.containers.windows.{WindowsEsPortProvider, WindowsPseudoEsContainer} import tech.beshu.ror.utils.httpclient.RestClient import tech.beshu.ror.utils.misc.OsUtils import tech.beshu.ror.utils.misc.OsUtils.CurrentOs @@ -53,11 +53,17 @@ abstract class EsContainer(val esVersion: String, private val esClient = Coeval(adminClient) - private val waitStrategy = new ElasticsearchNodeWaitingStrategy(esVersion, esConfig.nodeName, esClient, initializer, awaitingReadyStrategy) - private val containerImplementation: EsContainerImplementation = { OsUtils.currentOs match { case CurrentOs.Windows => + val waitStrategy = new ElasticsearchNodeWaitingStrategy( + esVersion = esVersion, + esPort = WindowsEsPortProvider.get(esConfig.nodeName).esPort, + containerName = esConfig.nodeName, + restClient = esClient, + initializer = initializer, + strategy = awaitingReadyStrategy + ) EsContainerImplementation.Windows( container = new WindowsPseudoEsContainer(elasticsearch, waitStrategy, additionalLogConsumer), ) @@ -69,6 +75,14 @@ abstract class EsContainer(val esVersion: String, case Some(additional) => new CompositeLogConsumer(slf4jConsumer, additional) case scala.None => slf4jConsumer } + val waitStrategy = new ElasticsearchNodeWaitingStrategy( + esVersion = esVersion, + esPort = 9200, + containerName = esConfig.nodeName, + restClient = esClient, + initializer = initializer, + strategy = awaitingReadyStrategy + ) container.setLogConsumers((logConsumer :: Nil).asJava) container.addExposedPort(9200) container.addExposedPort(9300) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/OpenLdapContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/OpenLdapContainer.scala index e687e98ea7..eeb7d427ef 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/OpenLdapContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/OpenLdapContainer.scala @@ -16,7 +16,6 @@ */ package tech.beshu.ror.utils.containers -import better.files.Dispose import better.files.Dispose.FlatMap.Implicits import com.dimafeng.testcontainers.GenericContainer import com.typesafe.scalalogging.LazyLogging @@ -24,7 +23,7 @@ import com.unboundid.ldap.sdk.{LDAPConnection, ResultCode} import monix.eval.Task import monix.execution.Scheduler.Implicits.global import org.testcontainers.containers.Network -import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy +import org.testcontainers.containers.wait.strategy.{AbstractWaitStrategy, HostPortWaitStrategy} import tech.beshu.ror.utils.containers.LdapContainer.{InitScriptSource, defaults, initLdap} import tech.beshu.ror.utils.containers.LdapWaitStrategy.* import tech.beshu.ror.utils.misc.ScalaUtils.* @@ -96,12 +95,18 @@ object NonStoppableOpenLdapContainer { private class LdapWaitStrategy(name: String, ldapInitScript: InitScriptSource) - extends HostPortWaitStrategy() + extends AbstractWaitStrategy with LazyLogging with Implicits { + private val underlying = HostPortWaitStrategy().forPorts(OpenLdapContainer.port, OpenLdapContainer.sslPort) + override def waitUntilReady(): Unit = { - super.waitUntilReady() + underlying.waitUntilReady(this.waitStrategyTarget) + waitForLdapInitialization() + } + + private def waitForLdapInitialization(): Unit = { logger.info(s"Waiting for LDAP container '$name' ...") retryBackoff(ldapInitiate(), 15, 1 second, 1) .onErrorHandle { ex => @@ -113,12 +118,12 @@ private class LdapWaitStrategy(name: String, } private def ldapInitiate() = { - runOnBindedLdapConnection { connection => + runOnBoundLdapConnection { connection => initLdap(connection, ldapInitScript) } } - private def runOnBindedLdapConnection(action: LDAPConnection => Unit): Task[Unit] = { + private def runOnBoundLdapConnection(action: LDAPConnection => Unit): Task[Unit] = { defaults.ldap.bindDn match { case Some(bindDn) => Task(new LDAPConnection(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(OpenLdapContainer.port))) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala index 2ee338db09..4f5eec3552 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala @@ -61,6 +61,7 @@ object WindowsEsPortProvider { "ror_xpack_cluster_3", "testEsCluster_1", "testEsCluster_2", + "testEsCluster_3", ).map(nodeName => (nodeName, nextPorts)) ) From 27148badf98b8345879697dfc11e97869e6df53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Mon, 15 Dec 2025 23:44:42 +0100 Subject: [PATCH 079/103] wip --- .../ror/integration/suites/RorStartingResponseCodeSuite.scala | 2 +- .../ror/utils/containers/windows/WindowsEsPortProvider.scala | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index bf5e3bf329..44d3c5c48c 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -135,7 +135,7 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { } private def createEsContainer: EsContainer = { - val clusterName = s"testEsCluster_${uniqueClusterId.getAndIncrement()}" + val clusterName = s"startingTest_EsCluster_${uniqueClusterId.getAndIncrement()}" val nodeName = clusterName create( nodeSettings = EsNodeSettings( diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala index 4f5eec3552..e41948f60f 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala @@ -61,7 +61,9 @@ object WindowsEsPortProvider { "ror_xpack_cluster_3", "testEsCluster_1", "testEsCluster_2", - "testEsCluster_3", + "startingTest_EsCluster_1", + "startingTest_EsCluster_2", + "startingTest_EsCluster_3", ).map(nodeName => (nodeName, nextPorts)) ) From c91f498772a2914ed821468abd9d4bd6e543c6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 09:42:15 +0100 Subject: [PATCH 080/103] fix --- core/src/test/resources/coredns-image/Dockerfile | 3 +-- .../tech/beshu/ror/utils/containers/DnsServerContainer.scala | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/test/resources/coredns-image/Dockerfile b/core/src/test/resources/coredns-image/Dockerfile index 4ca797e91e..d85069f443 100644 --- a/core/src/test/resources/coredns-image/Dockerfile +++ b/core/src/test/resources/coredns-image/Dockerfile @@ -1,7 +1,6 @@ -FROM coredns/coredns:1.8.0 +FROM coredns/coredns:1.13.2 EXPOSE 53/udp COPY Corefile /Corefile COPY conf /conf - diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala index 504cae4fb5..9ef1b91493 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala @@ -42,8 +42,8 @@ class DnsServerContainer(srvServicePort: Int) new ExposedPort(53, InternetProtocol.UDP) :: cmd.getExposedPorts.toList: _* ) - val ports = cmd.getPortBindings - ports.bind(ExposedPort.udp(53), Ports.Binding.empty()) + val ports = new Ports() + ports.bind(ExposedPort.udp(53), Ports.Binding.bindPort(0)) cmd.withPortBindings(ports) } From e5dbdadc66dad73344863886bcc71f226ef0a6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 10:35:15 +0100 Subject: [PATCH 081/103] fix --- .../ElasticsearchNodeWaitingStrategy.scala | 31 ++++--- .../utils/containers/WireMockContainer.java | 13 +-- .../ror/utils/elasticsearch/BaseManager.scala | 10 +-- .../ror/utils/httpclient/RestClient.scala | 23 +++++- .../ror/utils/misc/EsStartupChecker.scala | 81 +++++++++++-------- .../beshu/ror/utils/misc/ScalaUtils.scala | 3 + 6 files changed, 104 insertions(+), 57 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala index 5d110aad15..d3b2f51996 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ElasticsearchNodeWaitingStrategy.scala @@ -22,8 +22,10 @@ import org.testcontainers.containers.ContainerLaunchException import org.testcontainers.containers.wait.strategy.{AbstractWaitStrategy, HttpWaitStrategy} import tech.beshu.ror.utils.containers.ElasticsearchNodeWaitingStrategy.AwaitingReadyStrategy import tech.beshu.ror.utils.httpclient.RestClient -import tech.beshu.ror.utils.misc.{EsStartupChecker, Version} +import tech.beshu.ror.utils.misc.OsUtils.CurrentOs +import tech.beshu.ror.utils.misc.{EsStartupChecker, OsUtils, Version} +import scala.language.postfixOps import scala.util.Try class ElasticsearchNodeWaitingStrategy(esVersion: String, @@ -46,11 +48,11 @@ class ElasticsearchNodeWaitingStrategy(esVersion: String, private def waitForStart(client: RestClient) = { strategy match { case AwaitingReadyStrategy.WaitForEsReadiness => - createChecker(client).waitForStart() + createWaitForReadinessChecker(client).waitForStart() case AwaitingReadyStrategy.ImmediatelyTreatAsReady => true case AwaitingReadyStrategy.WaitForEsRestApiResponsive => - waitForRestEsApi() + waitForRestEsApi(client) } } @@ -66,7 +68,7 @@ class ElasticsearchNodeWaitingStrategy(esVersion: String, restClient.runAttempt().fold(throw _, identity) } - private def createChecker(client: RestClient) = { + private def createWaitForReadinessChecker(client: RestClient) = { if (Version.greaterOrEqualThan(esVersion, 8, 3, 0)) { EsStartupChecker.greenEsClusterChecker(containerName, client) } else { @@ -74,13 +76,20 @@ class ElasticsearchNodeWaitingStrategy(esVersion: String, } } - private def waitForRestEsApi() = { - val esRestApiWaitStrategy = new HttpWaitStrategy() - .usingTls().allowInsecure() - .forPort(esPort) - .forPath("/") - .forStatusCodeMatching(_ => true) - Try(esRestApiWaitStrategy.waitUntilReady(waitStrategyTarget)).isSuccess + private def waitForRestEsApi(client: RestClient) = { + OsUtils.currentOs match { + case CurrentOs.Windows => + EsStartupChecker + .reachableEsChecker(containerName, client) + .waitForStart() + case CurrentOs.OtherThanWindows => + val esRestApiWaitStrategy = new HttpWaitStrategy() + .usingTls().allowInsecure() + .forPort(esPort) + .forPath("/") + .forStatusCodeMatching(_ => true) + Try(esRestApiWaitStrategy.waitUntilReady(waitStrategyTarget)).isSuccess + } } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/WireMockContainer.java b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/WireMockContainer.java index 464a788ed8..5140dbe6dd 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/WireMockContainer.java +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/WireMockContainer.java @@ -47,8 +47,8 @@ private WireMockContainer(ImageFromDockerfile imageFromDockerfile) { public static WireMockContainer create(String... mappings) { ImageFromDockerfile dockerfile = new ImageFromDockerfile(); List mappingFiles = Lists.newArrayList(mappings).stream() - .map(ContainerUtils::getResourceFile) - .collect(Collectors.toList()); + .map(ContainerUtils::getResourceFile) + .collect(Collectors.toList()); mappingFiles.forEach(mappingFile -> dockerfile.withFileFromFile(mappingFile.getName(), mappingFile)); logger.info("Creating WireMock container ..."); WireMockContainer container = new WireMockContainer( @@ -61,7 +61,7 @@ public static WireMockContainer create(String... mappings) { .withExposedPorts(WIRE_MOCK_PORT) .waitingFor( container.waitStrategy() - .withStartupTimeout(CONTAINER_STARTUP_TIMEOUT) + .withStartupTimeout(CONTAINER_STARTUP_TIMEOUT) ); cont.setNetwork(Network.SHARED); @@ -87,9 +87,10 @@ private WaitStrategy waitStrategy() { protected boolean isReady() { try { RestClient client = getClient(); - return client - .execute(new HttpGet(client.from("/__admin/"))) - .getStatusLine().getStatusCode() == 200; + return client.handle( + new HttpGet(client.from("/__admin/")), + r -> r.getStatusLine().getStatusCode() == 200 + ); } catch (Exception e) { return false; } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala index 7c2c4ee21b..c2b616b12e 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/elasticsearch/BaseManager.scala @@ -27,7 +27,6 @@ import tech.beshu.ror.utils.elasticsearch.BaseManager.{JSON, SimpleHeader} import tech.beshu.ror.utils.httpclient.HttpResponseHelper.stringBodyFrom import tech.beshu.ror.utils.httpclient.RestClient import tech.beshu.ror.utils.misc.OsUtils.CurrentOs -import tech.beshu.ror.utils.misc.ScalaUtils.* import tech.beshu.ror.utils.misc.{OsUtils, Version} import java.time.Duration @@ -42,14 +41,15 @@ abstract class BaseManager(client: RestClient, protected def call[T <: SimpleResponse](request: HttpUriRequest, fromResponse: HttpResponse => T): T = { client - .execute { - additionalHeaders.foldLeft(request) { + .handle( + request = additionalHeaders.foldLeft(request) { case (req, (name, value)) => req.addHeader(name, value) req } - } - .bracket(fromResponse) + )( + fromResponse = fromResponse + ) } protected[elasticsearch] def eventually[T <: SimpleResponse](action: => T) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/httpclient/RestClient.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/httpclient/RestClient.scala index 96011e2eec..f2ff250187 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/httpclient/RestClient.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/httpclient/RestClient.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.utils.httpclient +import cats.effect.Resource import monix.eval.Task import monix.execution.Scheduler.Implicits.global import org.apache.http.auth.UsernamePasswordCredentials @@ -60,7 +61,27 @@ class RestClient(ssl: Boolean, def from(path: String): URI = buildUri(path, Map.empty) - def execute(req: HttpUriRequest): CloseableHttpResponse = { + def executeAsync(request: HttpUriRequest): Resource[Task, HttpResponse] = { + Resource + .make( + Task.delay(callExecute(request)) + )( + response => Task.delay(response.close()) + ) + } + + def executeSync[T](request: HttpUriRequest): Unit = { + handle(request)(identity) + } + + def handle[T](request: HttpUriRequest) + (fromResponse: HttpResponse => T): T = { + executeAsync(request) + .use(response => Task.delay(fromResponse(response))) + .runSyncUnsafe() + } + + private def callExecute(req: HttpUriRequest): CloseableHttpResponse = { Task(underlying.execute(req)) .onErrorRestartLoop(0) { case (ex: HttpHostConnectException, 10, _) => diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/EsStartupChecker.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/EsStartupChecker.scala index 5fe884a0ef..2067784065 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/EsStartupChecker.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/EsStartupChecker.scala @@ -16,11 +16,10 @@ */ package tech.beshu.ror.utils.misc -import cats.effect.Resource -import cats.implicits.* import com.typesafe.scalalogging.LazyLogging import monix.eval.Task import monix.execution.Scheduler.Implicits.global +import org.apache.http.HttpResponse import org.apache.http.client.methods.HttpGet import tech.beshu.ror.utils.httpclient.HttpResponseHelper.deserializeJsonBody import tech.beshu.ror.utils.httpclient.RestClient @@ -43,41 +42,52 @@ class EsStartupChecker private(name: String, } private def clusterIsReady(client: RestClient): Task[Unit] = { - Resource - .make( - Task - .delay(client.execute(new HttpGet(client.from("_cluster/health")))) - .recoverWith { ex => - logger.error(s"[$name] ES not ready yet, healthcheck failed") - Task.raiseError(ex) - } - )( - response => Task.delay(response.close()) - ) + client + .executeAsync(new HttpGet(client.from("_cluster/health"))) .use { response => - response.getStatusLine.getStatusCode match { - case 200 => - mode match { - case Mode.GreenCluster => - val healthJson = deserializeJsonBody(RestClient.bodyFrom(response)) - val healthStatus = healthJson.get("status") - if (healthStatus == "green") { - logger.info(s"[$name] ES is ready") - Task.unit - } else { - logger.info(s"[$name] ES not ready yet, health status is $healthStatus") - Task.raiseError(ClusterNotReady) - } - case Mode.Accessible => - logger.info(s"[$name] ES is ready") - Task.unit - } - case otherStatus => - logger.info(s"[$name] ES not ready yet, received HTTP $otherStatus") - Task.raiseError(ClusterNotReady) + val isOk = mode match { + case Mode.GreenCluster => isClusterGreen(response) + case Mode.Accessible => isClusterAccessible(response) + case Mode.Reachable => isClusterReachable(response) } + if(isOk) Task.unit + else Task.raiseError(ClusterNotReady) } } + + private def isClusterGreen(response: HttpResponse) = { + response.getStatusLine.getStatusCode match { + case 200 => + val healthJson = deserializeJsonBody(RestClient.bodyFrom(response)) + healthJson.get("status") match { + case "green" => + logger.info(s"[$name] ES is ready") + true + case healthStatus => + logger.info(s"[$name] ES not ready yet, health status is $healthStatus") + false + } + case otherStatus => + logger.info(s"[$name] ES not ready yet, received HTTP $otherStatus") + false + } + } + + private def isClusterAccessible(response: HttpResponse) = { + response.getStatusLine.getStatusCode match { + case 200 => + logger.info(s"[$name] ES is ready") + true + case otherStatus => + logger.info(s"[$name] ES not ready yet, received HTTP $otherStatus") + false + } + } + + private def isClusterReachable(response: HttpResponse) = { + logger.info(s"[$name] ES is reachable") + true + } } object EsStartupChecker { @@ -90,11 +100,14 @@ object EsStartupChecker { def accessibleEsChecker(name: String, client: RestClient): EsStartupChecker = new EsStartupChecker(name, client, Mode.Accessible) + def reachableEsChecker(name: String, client: RestClient): EsStartupChecker = + new EsStartupChecker(name, client, Mode.Reachable) + private sealed trait Mode private object Mode { case object GreenCluster extends Mode - case object Accessible extends Mode + case object Reachable extends Mode } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/ScalaUtils.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/ScalaUtils.scala index f680af7729..0063a336fe 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/ScalaUtils.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/misc/ScalaUtils.scala @@ -23,6 +23,7 @@ import com.typesafe.scalalogging.LazyLogging import monix.eval.Task import java.time.format.DateTimeFormatter +import java.util.concurrent.TimeUnit import scala.annotation.tailrec import scala.concurrent.duration.* import scala.language.{implicitConversions, postfixOps} @@ -76,6 +77,8 @@ object ScalaUtils extends LazyLogging { implicit def finiteDurationToJavaDuration(interval: FiniteDuration): Duration = Duration.ofMillis(interval.toMillis) + implicit def javaDurationToFiniteDuration(interval: Duration): FiniteDuration = FiniteDuration(interval.toMillis, TimeUnit.MILLISECONDS) + def retry(times: Int, cleanBeforeRetrying: => Unit = ())(action: => Unit): Unit = { @tailrec def loop(attempt: Int): Unit = { From a09e72ab51d9d39b52a455863c697148d7b5c6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 11:11:43 +0100 Subject: [PATCH 082/103] fix --- .../beshu/ror/integration/suites/base/BaseAdminApiSuite.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala index 83d7c93aeb..6b0e25e855 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/base/BaseAdminApiSuite.scala @@ -627,7 +627,6 @@ trait BaseAdminApiSuite "provide a method for reload test settings engine" which { "is going to reload ROR test core with TTL" when { "settings are new and correct" in { - // todo: do we need settingsTtlString? def forceReload(rorSettingsResource: String, settingsTtl: FiniteDuration, settingsTtlString: String): Unit = { val testSettings = getResourceContent(rorSettingsResource) updateRorTestSettings(rorClients.head, testSettings, settingsTtl) From baf5982c09e8f6422aff61ebd7828c0463b2fbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 13:45:36 +0100 Subject: [PATCH 083/103] fix --- .../integration/suites/RorStartingResponseCodeSuite.scala | 5 +++-- .../utils/containers/windows/WindowsEsPortProvider.scala | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala index 44d3c5c48c..63f7583394 100644 --- a/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala +++ b/integration-tests/src/test/scala/tech/beshu/ror/integration/suites/RorStartingResponseCodeSuite.scala @@ -135,8 +135,9 @@ private object RorStartingResponseCodeSuite extends EsModulePatterns { } private def createEsContainer: EsContainer = { - val clusterName = s"startingTest_EsCluster_${uniqueClusterId.getAndIncrement()}" - val nodeName = clusterName + val id = uniqueClusterId.getAndIncrement() + val clusterName = s"startingTest_EsCluster_$id" + val nodeName = s"${clusterName}_1" create( nodeSettings = EsNodeSettings( clusterName = clusterName, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala index e41948f60f..57fbb2dba4 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/windows/WindowsEsPortProvider.scala @@ -61,9 +61,9 @@ object WindowsEsPortProvider { "ror_xpack_cluster_3", "testEsCluster_1", "testEsCluster_2", - "startingTest_EsCluster_1", - "startingTest_EsCluster_2", - "startingTest_EsCluster_3", + "startingTest_EsCluster_1_1", + "startingTest_EsCluster_2_1", + "startingTest_EsCluster_3_1", ).map(nodeName => (nodeName, nextPorts)) ) From 1adf1ce979c54ee2caee7e524b386b69e8ebc946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 22:54:14 +0100 Subject: [PATCH 084/103] fix --- .../internal/modifiers/BytecodeJarModifier.scala | 1 - .../ror/utils/containers/DnsServerContainer.scala | 4 +++- .../utils/containers/LdapWithDnsContainer.scala | 15 +++++++++++++-- .../ror/utils/containers/ToxiproxyContainer.scala | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala b/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala index bdc8800e72..21d535c3dc 100644 --- a/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala +++ b/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala @@ -17,7 +17,6 @@ package tech.beshu.ror.tools.core.patches.internal.modifiers import tech.beshu.ror.tools.core.utils.FileUtils.* -import tech.beshu.ror.tools.core.utils.FileUtils.javaFileToFile import java.io.{ByteArrayInputStream, File, InputStream} import java.net.URI diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala index 9ef1b91493..08f45bdb00 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala @@ -48,8 +48,10 @@ class DnsServerContainer(srvServicePort: Int) } def dnsPort: Int = { - // This is hack to obtain mapping of UDP port as testcontainers doesn't allow explicit mapping of UDP ports + // This is hack to obtain mapping of UDP port as testcontainers doesn't allow explicit mapping of UDP ports, // although it is mapping each port exposed by container(even UDP). + // Wait a bit to ensure port binding is ready + Thread.sleep(500) this.containerInfo .getNetworkSettings .getPorts diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala index eac59c9710..f93e287801 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala @@ -17,12 +17,17 @@ package tech.beshu.ror.utils.containers import com.dimafeng.testcontainers.Container +import org.testcontainers.containers.Network import tech.beshu.ror.utils.containers.LdapContainer.InitScriptSource class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) extends Container { - private val ldapContainer = OpenLdapContainer.create(name, ldapInitScript) + private val ldapContainer = { + val c = OpenLdapContainer.create(name, ldapInitScript) + c.underlyingUnsafeContainer.setNetwork(Network.SHARED) + c + } private var dnsContainer: Option[DnsServerContainer] = None @@ -30,7 +35,8 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) override def start(): Unit = { ldapContainer.start() - dnsContainer = Option(new DnsServerContainer(ldapContainer.ldapPort)) + + dnsContainer = Option(createDnsServerContainer()) dnsContainer.foreach(_.start()) } @@ -39,4 +45,9 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) dnsContainer.foreach(_.stop()) } + private def createDnsServerContainer() = { + val dns = new DnsServerContainer(ldapContainer.ldapPort) + dns.underlyingUnsafeContainer.setNetwork(Network.SHARED) + dns + } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 86e2e6f127..371bf01b7e 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -32,6 +32,7 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe waitStrategy = Some(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) ) { + innerContainer.underlyingUnsafeContainer.setNetwork(Network.SHARED) container.setNetwork(Network.SHARED) private var innerContainerProxy: Option[Proxy] = None From 2c2dcec2c2e045d72dd041d334033bfd1a101261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 23:06:17 +0100 Subject: [PATCH 085/103] fix --- .../internal/modifiers/BytecodeJarModifier.scala | 5 +++-- .../utils/containers/LdapWithDnsContainer.scala | 16 ++-------------- .../utils/containers/ToxiproxyContainer.scala | 12 ++++++++++-- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala b/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala index 21d535c3dc..36e0c94425 100644 --- a/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala +++ b/ror-tools-core/src/main/scala/tech/beshu/ror/tools/core/patches/internal/modifiers/BytecodeJarModifier.scala @@ -16,6 +16,7 @@ */ package tech.beshu.ror.tools.core.patches.internal.modifiers +import better.files.FileExtensions import tech.beshu.ror.tools.core.utils.FileUtils.* import java.io.{ByteArrayInputStream, File, InputStream} @@ -31,7 +32,7 @@ private[patches] abstract class BytecodeJarModifier(debugEnabled: Boolean = fals protected def modifyFileInJar(jar: File, filePathString: String, processFileContent: InputStream => Array[Byte]): Unit = { - val originalFilePermissionsAndOwner = jar.getFilePermissionsAndOwner + val originalFilePermissionsAndOwner = jar.toScala.getFilePermissionsAndOwner val modifiedFileContent = loadAndProcessFileFromJar( jar = jar, filePathString = filePathString, @@ -42,7 +43,7 @@ private[patches] abstract class BytecodeJarModifier(debugEnabled: Boolean = fals destinationPathSting = filePathString, newContent = modifiedFileContent ) - jar.setFilePermissionsAndOwner(originalFilePermissionsAndOwner) + jar.toScala.setFilePermissionsAndOwner(originalFilePermissionsAndOwner) } private def loadAndProcessFileFromJar(jar: File, diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala index f93e287801..24c8c8f69d 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala @@ -17,17 +17,12 @@ package tech.beshu.ror.utils.containers import com.dimafeng.testcontainers.Container -import org.testcontainers.containers.Network import tech.beshu.ror.utils.containers.LdapContainer.InitScriptSource class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) extends Container { - private val ldapContainer = { - val c = OpenLdapContainer.create(name, ldapInitScript) - c.underlyingUnsafeContainer.setNetwork(Network.SHARED) - c - } + private val ldapContainer = OpenLdapContainer.create(name, ldapInitScript) private var dnsContainer: Option[DnsServerContainer] = None @@ -35,8 +30,7 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) override def start(): Unit = { ldapContainer.start() - - dnsContainer = Option(createDnsServerContainer()) + dnsContainer = Option(new DnsServerContainer(ldapContainer.ldapPort)) dnsContainer.foreach(_.start()) } @@ -44,10 +38,4 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) ldapContainer.stop() dnsContainer.foreach(_.stop()) } - - private def createDnsServerContainer() = { - val dns = new DnsServerContainer(ldapContainer.ldapPort) - dns.underlyingUnsafeContainer.setNetwork(Network.SHARED) - dns - } } diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 371bf01b7e..b9e2885e64 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -20,6 +20,7 @@ import com.dimafeng.testcontainers.{GenericContainer, SingleContainer} import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network +import org.testcontainers.Testcontainers import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} import scala.concurrent.duration.* @@ -32,8 +33,8 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe waitStrategy = Some(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) ) { - innerContainer.underlyingUnsafeContainer.setNetwork(Network.SHARED) container.setNetwork(Network.SHARED) + container.withAccessToHost(true) private var innerContainerProxy: Option[Proxy] = None private var timeoutToxic: Option[toxic.Timeout] = None @@ -81,8 +82,15 @@ object ToxiproxyContainer { override protected def isReady: Boolean = { try { + val innerMappedPort = innerContainer.mappedPort(innerServicePort) + // Expose the inner container's mapped port on the host so toxiproxy can reach it + // This is required for testcontainers 2.0 to work on Linux + Testcontainers.exposeHostPorts(innerMappedPort) + val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"${innerContainer.containerInfo.getConfig.getHostName}:$innerServicePort") + // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container + // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 + toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"host.testcontainers.internal:$innerMappedPort") true } catch { case _: Exception => false From a79c00bcc26f2ba5bdeb4f0855c7634daaf112bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 23:33:22 +0100 Subject: [PATCH 086/103] fix --- .../ror/utils/containers/ToxiproxyContainer.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index b9e2885e64..b7bb3ecc78 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -62,6 +62,11 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe override def start(): Unit = { innerContainer.start() + // Expose the inner container's mapped port BEFORE starting toxiproxy + // This is required for host.testcontainers.internal to work on Linux + val innerMappedPort = innerContainer.mappedPort(innerServicePort) + Testcontainers.exposeHostPorts(innerMappedPort) + super.start() val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) @@ -83,13 +88,10 @@ object ToxiproxyContainer { override protected def isReady: Boolean = { try { val innerMappedPort = innerContainer.mappedPort(innerServicePort) - // Expose the inner container's mapped port on the host so toxiproxy can reach it - // This is required for testcontainers 2.0 to work on Linux - Testcontainers.exposeHostPorts(innerMappedPort) - val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 + // Note: exposeHostPorts must be called before container start (done in start() method) toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"host.testcontainers.internal:$innerMappedPort") true } catch { From 084c042fb71ec4ca4d9191f3c222fa4dcc79d2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Tue, 16 Dec 2025 23:55:42 +0100 Subject: [PATCH 087/103] fix --- .../ror/utils/containers/ToxiproxyContainer.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index b7bb3ecc78..9c59eb5a4d 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -89,13 +89,19 @@ object ToxiproxyContainer { try { val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) + val proxyUpstream = s"host.testcontainers.internal:$innerMappedPort" + println(s"[TOXIPROXY DEBUG] Creating proxy: listen=[::]:$proxiedPort upstream=$proxyUpstream") // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 // Note: exposeHostPorts must be called before container start (done in start() method) - toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"host.testcontainers.internal:$innerMappedPort") + toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", proxyUpstream) + println(s"[TOXIPROXY DEBUG] Proxy created successfully") true } catch { - case _: Exception => false + case ex: Exception => + println(s"[TOXIPROXY DEBUG] Failed to create proxy: ${ex.getClass.getName}: ${ex.getMessage}") + ex.printStackTrace() + false } } } From 1990cd84da1c00f67afd59e801c36eed8a278e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 00:07:49 +0100 Subject: [PATCH 088/103] fix --- .../beshu/ror/utils/containers/ToxiproxyContainer.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 9c59eb5a4d..08b3ee6be0 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -90,11 +90,13 @@ object ToxiproxyContainer { val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) val proxyUpstream = s"host.testcontainers.internal:$innerMappedPort" - println(s"[TOXIPROXY DEBUG] Creating proxy: listen=[::]:$proxiedPort upstream=$proxyUpstream") + val proxyListen = s"0.0.0.0:$proxiedPort" + println(s"[TOXIPROXY DEBUG] Creating proxy: listen=$proxyListen upstream=$proxyUpstream") // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 // Note: exposeHostPorts must be called before container start (done in start() method) - toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", proxyUpstream) + // Use 0.0.0.0 instead of [::] for better Linux compatibility + toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) println(s"[TOXIPROXY DEBUG] Proxy created successfully") true } catch { From 5ef6ea8f8735b4b266629f531256a9712aee2fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 09:27:30 +0100 Subject: [PATCH 089/103] check --- .../ror/utils/containers/ToxiproxyContainer.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 08b3ee6be0..98aca9db26 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -65,12 +65,14 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe // Expose the inner container's mapped port BEFORE starting toxiproxy // This is required for host.testcontainers.internal to work on Linux val innerMappedPort = innerContainer.mappedPort(innerServicePort) + println(s"[TOXIPROXY DEBUG] Exposing host port: $innerMappedPort") Testcontainers.exposeHostPorts(innerMappedPort) super.start() val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) innerContainerProxy = Some(toxiproxyClient.getProxy("proxy")) + println(s"[TOXIPROXY DEBUG] Toxiproxy container mapped port (proxiedPort=$proxiedPort): ${container.getMappedPort(proxiedPort)}") } override def stop(): Unit = { @@ -92,12 +94,18 @@ object ToxiproxyContainer { val proxyUpstream = s"host.testcontainers.internal:$innerMappedPort" val proxyListen = s"0.0.0.0:$proxiedPort" println(s"[TOXIPROXY DEBUG] Creating proxy: listen=$proxyListen upstream=$proxyUpstream") + println(s"[TOXIPROXY DEBUG] Inner container service port: $innerServicePort, mapped to: $innerMappedPort") // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 // Note: exposeHostPorts must be called before container start (done in start() method) // Use 0.0.0.0 instead of [::] for better Linux compatibility - toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) - println(s"[TOXIPROXY DEBUG] Proxy created successfully") + val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) + println(s"[TOXIPROXY DEBUG] Proxy created successfully. Proxy details: ${proxy.getName}, listen=${proxy.getListen}, upstream=${proxy.getUpstream}") + + // Test if we can list proxies + val allProxies = toxiproxyClient.getProxies + println(s"[TOXIPROXY DEBUG] All proxies count: ${allProxies.size()}") + true } catch { case ex: Exception => From 90c009364002067268b841b39f5fb836bcaa3157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 09:41:50 +0100 Subject: [PATCH 090/103] check --- .../utils/containers/ToxiproxyContainer.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 98aca9db26..37c853e0c9 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -68,6 +68,9 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe println(s"[TOXIPROXY DEBUG] Exposing host port: $innerMappedPort") Testcontainers.exposeHostPorts(innerMappedPort) + // Small delay to ensure Testcontainers has time to register the port before we start toxiproxy + Thread.sleep(100) + super.start() val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) @@ -102,10 +105,25 @@ object ToxiproxyContainer { val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) println(s"[TOXIPROXY DEBUG] Proxy created successfully. Proxy details: ${proxy.getName}, listen=${proxy.getListen}, upstream=${proxy.getUpstream}") + // Test connectivity from toxiproxy to upstream by enabling the proxy + proxy.enable() + println(s"[TOXIPROXY DEBUG] Proxy enabled") + // Test if we can list proxies val allProxies = toxiproxyClient.getProxies println(s"[TOXIPROXY DEBUG] All proxies count: ${allProxies.size()}") + // Test actual connectivity through the proxy by trying to connect to the mapped port + try { + val socket = new java.net.Socket() + socket.connect(new java.net.InetSocketAddress("localhost", waitStrategyTarget.getMappedPort(proxiedPort)), 1000) + socket.close() + println(s"[TOXIPROXY DEBUG] Successfully connected to toxiproxy mapped port: ${waitStrategyTarget.getMappedPort(proxiedPort)}") + } catch { + case ex: Exception => + println(s"[TOXIPROXY DEBUG] Failed to connect to toxiproxy mapped port: ${ex.getMessage}") + } + true } catch { case ex: Exception => From ae45b37d144331838442bf22a43dc6c10c67594a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 09:54:16 +0100 Subject: [PATCH 091/103] check --- .../utils/containers/ToxiproxyContainer.scala | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 37c853e0c9..8cd87bf06e 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -95,33 +95,44 @@ object ToxiproxyContainer { val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) val proxyUpstream = s"host.testcontainers.internal:$innerMappedPort" + // Use format "HOST:PORT" - toxiproxy will parse and bind correctly val proxyListen = s"0.0.0.0:$proxiedPort" println(s"[TOXIPROXY DEBUG] Creating proxy: listen=$proxyListen upstream=$proxyUpstream") println(s"[TOXIPROXY DEBUG] Inner container service port: $innerServicePort, mapped to: $innerMappedPort") // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 // Note: exposeHostPorts must be called before container start (done in start() method) - // Use 0.0.0.0 instead of [::] for better Linux compatibility val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) println(s"[TOXIPROXY DEBUG] Proxy created successfully. Proxy details: ${proxy.getName}, listen=${proxy.getListen}, upstream=${proxy.getUpstream}") - // Test connectivity from toxiproxy to upstream by enabling the proxy + // Enable the proxy proxy.enable() println(s"[TOXIPROXY DEBUG] Proxy enabled") - // Test if we can list proxies - val allProxies = toxiproxyClient.getProxies - println(s"[TOXIPROXY DEBUG] All proxies count: ${allProxies.size()}") + // Give toxiproxy a moment to start listening + Thread.sleep(200) // Test actual connectivity through the proxy by trying to connect to the mapped port + val mappedPort = waitStrategyTarget.getMappedPort(proxiedPort) + println(s"[TOXIPROXY DEBUG] Testing connection to localhost:$mappedPort") try { val socket = new java.net.Socket() - socket.connect(new java.net.InetSocketAddress("localhost", waitStrategyTarget.getMappedPort(proxiedPort)), 1000) + socket.connect(new java.net.InetSocketAddress("127.0.0.1", mappedPort), 2000) socket.close() - println(s"[TOXIPROXY DEBUG] Successfully connected to toxiproxy mapped port: ${waitStrategyTarget.getMappedPort(proxiedPort)}") + println(s"[TOXIPROXY DEBUG] Successfully connected to toxiproxy mapped port: $mappedPort") } catch { case ex: Exception => - println(s"[TOXIPROXY DEBUG] Failed to connect to toxiproxy mapped port: ${ex.getMessage}") + println(s"[TOXIPROXY DEBUG] Failed to connect to toxiproxy mapped port $mappedPort: ${ex.getClass.getName}: ${ex.getMessage}") + // Try IPv6 + try { + val socket6 = new java.net.Socket() + socket6.connect(new java.net.InetSocketAddress("::1", mappedPort), 2000) + socket6.close() + println(s"[TOXIPROXY DEBUG] Successfully connected via IPv6 to toxiproxy mapped port: $mappedPort") + } catch { + case ex6: Exception => + println(s"[TOXIPROXY DEBUG] Failed to connect via IPv6 to toxiproxy mapped port $mappedPort: ${ex6.getClass.getName}: ${ex6.getMessage}") + } } true From 749d5adaa3ae00525ce2df30773370c1148b5adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 10:06:35 +0100 Subject: [PATCH 092/103] check --- .../ror/utils/containers/ToxiproxyContainer.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 8cd87bf06e..573f563fcf 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -72,6 +72,20 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe Thread.sleep(100) super.start() + + // Debug: Check /etc/hosts and connectivity from inside toxiproxy container + try { + val hostsOutput = container.execInContainer("cat", "/etc/hosts") + println(s"[TOXIPROXY DEBUG] /etc/hosts from toxiproxy container:") + println(hostsOutput.getStdout) + + val pingOutput = container.execInContainer("sh", "-c", "getent hosts host.testcontainers.internal || echo 'FAILED TO RESOLVE'") + println(s"[TOXIPROXY DEBUG] getent hosts host.testcontainers.internal:") + println(pingOutput.getStdout) + } catch { + case ex: Exception => + println(s"[TOXIPROXY DEBUG] Failed to exec diagnostics: ${ex.getMessage}") + } val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) innerContainerProxy = Some(toxiproxyClient.getProxy("proxy")) From 581e34d74e54f64b7738142c70a504967151672c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 10:19:43 +0100 Subject: [PATCH 093/103] check --- .../utils/containers/ToxiproxyContainer.scala | 86 +++++-------------- 1 file changed, 23 insertions(+), 63 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 573f563fcf..89744e9803 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -20,9 +20,9 @@ import com.dimafeng.testcontainers.{GenericContainer, SingleContainer} import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network -import org.testcontainers.Testcontainers import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} +import scala.annotation.nowarn import scala.concurrent.duration.* import scala.language.postfixOps @@ -34,7 +34,6 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe ) { container.setNetwork(Network.SHARED) - container.withAccessToHost(true) private var innerContainerProxy: Option[Proxy] = None private var timeoutToxic: Option[toxic.Timeout] = None @@ -62,34 +61,10 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe override def start(): Unit = { innerContainer.start() - // Expose the inner container's mapped port BEFORE starting toxiproxy - // This is required for host.testcontainers.internal to work on Linux - val innerMappedPort = innerContainer.mappedPort(innerServicePort) - println(s"[TOXIPROXY DEBUG] Exposing host port: $innerMappedPort") - Testcontainers.exposeHostPorts(innerMappedPort) - - // Small delay to ensure Testcontainers has time to register the port before we start toxiproxy - Thread.sleep(100) - super.start() - - // Debug: Check /etc/hosts and connectivity from inside toxiproxy container - try { - val hostsOutput = container.execInContainer("cat", "/etc/hosts") - println(s"[TOXIPROXY DEBUG] /etc/hosts from toxiproxy container:") - println(hostsOutput.getStdout) - - val pingOutput = container.execInContainer("sh", "-c", "getent hosts host.testcontainers.internal || echo 'FAILED TO RESOLVE'") - println(s"[TOXIPROXY DEBUG] getent hosts host.testcontainers.internal:") - println(pingOutput.getStdout) - } catch { - case ex: Exception => - println(s"[TOXIPROXY DEBUG] Failed to exec diagnostics: ${ex.getMessage}") - } val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) innerContainerProxy = Some(toxiproxyClient.getProxy("proxy")) - println(s"[TOXIPROXY DEBUG] Toxiproxy container mapped port (proxiedPort=$proxiedPort): ${container.getMappedPort(proxiedPort)}") } override def stop(): Unit = { @@ -104,50 +79,35 @@ object ToxiproxyContainer { private class ToxiproxyWaitStrategy(innerContainer: SingleContainer[_], innerServicePort: Int) extends WaitWithRetriesStrategy("toxiproxy") { + @nowarn("cat=deprecation") override protected def isReady: Boolean = { try { val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - val proxyUpstream = s"host.testcontainers.internal:$innerMappedPort" - // Use format "HOST:PORT" - toxiproxy will parse and bind correctly - val proxyListen = s"0.0.0.0:$proxiedPort" - println(s"[TOXIPROXY DEBUG] Creating proxy: listen=$proxyListen upstream=$proxyUpstream") - println(s"[TOXIPROXY DEBUG] Inner container service port: $innerServicePort, mapped to: $innerMappedPort") - // Use host.testcontainers.internal to reference the host machine from within the toxiproxy container - // This works cross-platform (Mac, Windows, Linux) in testcontainers 2.0 - // Note: exposeHostPorts must be called before container start (done in start() method) - val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) - println(s"[TOXIPROXY DEBUG] Proxy created successfully. Proxy details: ${proxy.getName}, listen=${proxy.getListen}, upstream=${proxy.getUpstream}") - // Enable the proxy - proxy.enable() - println(s"[TOXIPROXY DEBUG] Proxy enabled") + // Get the gateway IP from the toxiproxy container's network settings + // This is the IP address that toxiproxy can use to reach the host machine + val networks = waitStrategyTarget.getContainerInfo.getNetworkSettings.getNetworks + val gatewayIp = if (networks.isEmpty) { + // Fallback to deprecated method if networks are empty (shouldn't happen) + waitStrategyTarget.getContainerInfo.getNetworkSettings.getGateway + } else { + // Get gateway from the first network (usually bridge or the shared network) + networks.values().iterator().next().getGateway + } + + val proxyUpstream = s"$gatewayIp:$innerMappedPort" + val proxyListen = s"0.0.0.0:$proxiedPort" - // Give toxiproxy a moment to start listening - Thread.sleep(200) + println(s"[TOXIPROXY DEBUG] Creating proxy:") + println(s"[TOXIPROXY DEBUG] listen=$proxyListen") + println(s"[TOXIPROXY DEBUG] upstream=$proxyUpstream (gateway IP)") + println(s"[TOXIPROXY DEBUG] Inner container service port: $innerServicePort, mapped to: $innerMappedPort") - // Test actual connectivity through the proxy by trying to connect to the mapped port - val mappedPort = waitStrategyTarget.getMappedPort(proxiedPort) - println(s"[TOXIPROXY DEBUG] Testing connection to localhost:$mappedPort") - try { - val socket = new java.net.Socket() - socket.connect(new java.net.InetSocketAddress("127.0.0.1", mappedPort), 2000) - socket.close() - println(s"[TOXIPROXY DEBUG] Successfully connected to toxiproxy mapped port: $mappedPort") - } catch { - case ex: Exception => - println(s"[TOXIPROXY DEBUG] Failed to connect to toxiproxy mapped port $mappedPort: ${ex.getClass.getName}: ${ex.getMessage}") - // Try IPv6 - try { - val socket6 = new java.net.Socket() - socket6.connect(new java.net.InetSocketAddress("::1", mappedPort), 2000) - socket6.close() - println(s"[TOXIPROXY DEBUG] Successfully connected via IPv6 to toxiproxy mapped port: $mappedPort") - } catch { - case ex6: Exception => - println(s"[TOXIPROXY DEBUG] Failed to connect via IPv6 to toxiproxy mapped port $mappedPort: ${ex6.getClass.getName}: ${ex6.getMessage}") - } - } + // Create proxy pointing to the host's gateway IP + mapped port + // From inside toxiproxy container, we reach the host via the Docker bridge gateway + toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) + println(s"[TOXIPROXY DEBUG] Proxy created successfully") true } catch { From f9b88369d9beb6a7676849483dac857686f49ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 10:51:01 +0100 Subject: [PATCH 094/103] check --- .../utils/containers/ToxiproxyContainer.scala | 40 ++++--------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 89744e9803..1267cf62ee 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -17,18 +17,18 @@ package tech.beshu.ror.utils.containers import com.dimafeng.testcontainers.{GenericContainer, SingleContainer} +import com.typesafe.scalalogging.LazyLogging import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} -import scala.annotation.nowarn import scala.concurrent.duration.* import scala.language.postfixOps class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerServicePort: Int) extends GenericContainer( - dockerImage = "ghcr.io/shopify/toxiproxy:2.12.0", + dockerImage = "shopify/toxiproxy:2.1.4", exposedPorts = Seq(httpApiPort, proxiedPort), waitStrategy = Some(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) ) { @@ -77,43 +77,17 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe object ToxiproxyContainer { private class ToxiproxyWaitStrategy(innerContainer: SingleContainer[_], innerServicePort: Int) - extends WaitWithRetriesStrategy("toxiproxy") { + extends WaitWithRetriesStrategy("toxiproxy") + with LazyLogging { - @nowarn("cat=deprecation") override protected def isReady: Boolean = { try { - val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - - // Get the gateway IP from the toxiproxy container's network settings - // This is the IP address that toxiproxy can use to reach the host machine - val networks = waitStrategyTarget.getContainerInfo.getNetworkSettings.getNetworks - val gatewayIp = if (networks.isEmpty) { - // Fallback to deprecated method if networks are empty (shouldn't happen) - waitStrategyTarget.getContainerInfo.getNetworkSettings.getGateway - } else { - // Get gateway from the first network (usually bridge or the shared network) - networks.values().iterator().next().getGateway - } - - val proxyUpstream = s"$gatewayIp:$innerMappedPort" - val proxyListen = s"0.0.0.0:$proxiedPort" - - println(s"[TOXIPROXY DEBUG] Creating proxy:") - println(s"[TOXIPROXY DEBUG] listen=$proxyListen") - println(s"[TOXIPROXY DEBUG] upstream=$proxyUpstream (gateway IP)") - println(s"[TOXIPROXY DEBUG] Inner container service port: $innerServicePort, mapped to: $innerMappedPort") - - // Create proxy pointing to the host's gateway IP + mapped port - // From inside toxiproxy container, we reach the host via the Docker bridge gateway - toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) - println(s"[TOXIPROXY DEBUG] Proxy created successfully") - + toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"${innerContainer.containerInfo.getConfig.getHostName}:$innerServicePort") true } catch { - case ex: Exception => - println(s"[TOXIPROXY DEBUG] Failed to create proxy: ${ex.getClass.getName}: ${ex.getMessage}") - ex.printStackTrace() + case ex: Throwable => + logger.debug("Toxic Proxy is not ready", ex) false } } From 8a4a795414a8e137d31bfac40daae7a3d64c3369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 11:15:33 +0100 Subject: [PATCH 095/103] check --- .../utils/containers/ToxiproxyContainer.scala | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 1267cf62ee..8e9c812054 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -23,6 +23,7 @@ import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} +import scala.annotation.nowarn import scala.concurrent.duration.* import scala.language.postfixOps @@ -80,10 +81,28 @@ object ToxiproxyContainer { extends WaitWithRetriesStrategy("toxiproxy") with LazyLogging { + @nowarn("cat=deprecation") override protected def isReady: Boolean = { try { + val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - toxiproxyClient.createProxy("proxy", s"[::]:$proxiedPort", s"${innerContainer.containerInfo.getConfig.getHostName}:$innerServicePort") + + // Get the gateway IP from the toxiproxy container's network settings + // This is the IP address that toxiproxy can use to reach the host machine + val networks = waitStrategyTarget.getContainerInfo.getNetworkSettings.getNetworks + val gatewayIp = if (networks.isEmpty) { + waitStrategyTarget.getContainerInfo.getNetworkSettings.getGateway + } else { + networks.values().iterator().next().getGateway + } + + val proxyUpstream = s"$gatewayIp:$innerMappedPort" + val proxyListen = s"0.0.0.0:$proxiedPort" + + logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (gateway IP)") + toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) + logger.debug(s"[TOXIPROXY] Proxy created successfully") + true } catch { case ex: Throwable => From b63c990d7468663480cfd0773f3d573f8d3c6b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 11:25:58 +0100 Subject: [PATCH 096/103] check --- .../utils/containers/ToxiproxyContainer.scala | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 8e9c812054..4ad59110bd 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -23,7 +23,6 @@ import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} -import scala.annotation.nowarn import scala.concurrent.duration.* import scala.language.postfixOps @@ -81,25 +80,24 @@ object ToxiproxyContainer { extends WaitWithRetriesStrategy("toxiproxy") with LazyLogging { - @nowarn("cat=deprecation") override protected def isReady: Boolean = { try { - val innerMappedPort = innerContainer.mappedPort(innerServicePort) val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - // Get the gateway IP from the toxiproxy container's network settings - // This is the IP address that toxiproxy can use to reach the host machine - val networks = waitStrategyTarget.getContainerInfo.getNetworkSettings.getNetworks - val gatewayIp = if (networks.isEmpty) { - waitStrategyTarget.getContainerInfo.getNetworkSettings.getGateway + // Get inner container's IP address on the shared network + val innerNetworks = innerContainer.underlyingUnsafeContainer.getContainerInfo.getNetworkSettings.getNetworks + val innerContainerIp = if (innerNetworks.isEmpty) { + // Fallback to hostname if network info is not available + innerContainer.containerInfo.getConfig.getHostName } else { - networks.values().iterator().next().getGateway + // Get IP address from the first network (should be Network.SHARED) + innerNetworks.values().iterator().next().getIpAddress } - val proxyUpstream = s"$gatewayIp:$innerMappedPort" + val proxyUpstream = s"$innerContainerIp:$innerServicePort" val proxyListen = s"0.0.0.0:$proxiedPort" - logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (gateway IP)") + logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (container IP)") toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) logger.debug(s"[TOXIPROXY] Proxy created successfully") From 7556d5a180c6532df00da4088477285e32c18a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 11:51:37 +0100 Subject: [PATCH 097/103] check --- .../beshu/ror/utils/containers/ToxiproxyContainer.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 4ad59110bd..88993bb17a 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -21,6 +21,7 @@ import com.typesafe.scalalogging.LazyLogging import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} import org.testcontainers.containers.Network +import org.testcontainers.containers.wait.strategy.{HostPortWaitStrategy, WaitAllStrategy} import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} import scala.concurrent.duration.* @@ -30,7 +31,11 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe extends GenericContainer( dockerImage = "shopify/toxiproxy:2.1.4", exposedPorts = Seq(httpApiPort, proxiedPort), - waitStrategy = Some(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) + waitStrategy = Some( + new WaitAllStrategy() + .withStrategy(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) + .withStrategy(new HostPortWaitStrategy()) + ) ) { container.setNetwork(Network.SHARED) From 22852c7375d2354b3d08062d910074ce295cb2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 12:08:23 +0100 Subject: [PATCH 098/103] check --- .../utils/containers/ToxiproxyContainer.scala | 103 ++++++++++-------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 88993bb17a..38ac941df0 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -20,10 +20,13 @@ import com.dimafeng.testcontainers.{GenericContainer, SingleContainer} import com.typesafe.scalalogging.LazyLogging import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} +import org.rnorth.ducttape.unreliables.Unreliables import org.testcontainers.containers.Network -import org.testcontainers.containers.wait.strategy.{HostPortWaitStrategy, WaitAllStrategy} -import tech.beshu.ror.utils.containers.ToxiproxyContainer.{ToxiproxyWaitStrategy, httpApiPort, proxiedPort} +import org.testcontainers.containers.wait.strategy.{WaitStrategy, WaitStrategyTarget} +import tech.beshu.ror.utils.containers.ToxiproxyContainer.{httpApiPort, proxiedPort} +import java.time.Duration +import java.util.concurrent.TimeUnit import scala.concurrent.duration.* import scala.language.postfixOps @@ -31,14 +34,11 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe extends GenericContainer( dockerImage = "shopify/toxiproxy:2.1.4", exposedPorts = Seq(httpApiPort, proxiedPort), - waitStrategy = Some( - new WaitAllStrategy() - .withStrategy(new ToxiproxyWaitStrategy(innerContainer, innerServicePort)) - .withStrategy(new HostPortWaitStrategy()) - ) - ) { + waitStrategy = Some(new ToxiproxyApiWaitStrategy()) + ) with LazyLogging { container.setNetwork(Network.SHARED) + container.withStartupTimeout(Duration.ofSeconds(120)) private var innerContainerProxy: Option[Proxy] = None private var timeoutToxic: Option[toxic.Timeout] = None @@ -67,9 +67,28 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe override def start(): Unit = { innerContainer.start() super.start() - + + // Create proxy AFTER both containers are fully started + // Fetch fresh container info to get the correct IP address + val dockerClient = container.getDockerClient + val freshContainerInfo = dockerClient.inspectContainerCmd(innerContainer.containerId).exec() + val innerNetworks = freshContainerInfo.getNetworkSettings.getNetworks + + val innerContainerIp = if (innerNetworks.isEmpty) { + innerContainer.containerInfo.getConfig.getHostName + } else { + innerNetworks.values().iterator().next().getIpAddress + } + + val proxyUpstream = s"$innerContainerIp:$innerServicePort" + val proxyListen = s"0.0.0.0:$proxiedPort" + + logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (container IP)") val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) - innerContainerProxy = Some(toxiproxyClient.getProxy("proxy")) + val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) + logger.debug(s"[TOXIPROXY] Proxy created successfully") + + innerContainerProxy = Some(proxy) } override def stop(): Unit = { @@ -79,42 +98,40 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe } -object ToxiproxyContainer { - - private class ToxiproxyWaitStrategy(innerContainer: SingleContainer[_], innerServicePort: Int) - extends WaitWithRetriesStrategy("toxiproxy") - with LazyLogging { - - override protected def isReady: Boolean = { - try { - val toxiproxyClient = new ToxiproxyClient(waitStrategyTarget.getHost, waitStrategyTarget.getMappedPort(httpApiPort)) - - // Get inner container's IP address on the shared network - val innerNetworks = innerContainer.underlyingUnsafeContainer.getContainerInfo.getNetworkSettings.getNetworks - val innerContainerIp = if (innerNetworks.isEmpty) { - // Fallback to hostname if network info is not available - innerContainer.containerInfo.getConfig.getHostName - } else { - // Get IP address from the first network (should be Network.SHARED) - innerNetworks.values().iterator().next().getIpAddress +private class ToxiproxyApiWaitStrategy extends WaitStrategy with LazyLogging { + private var startupTimeout: Duration = Duration.ofSeconds(60) + + override def waitUntilReady(waitStrategyTarget: WaitStrategyTarget): Unit = { + val host = waitStrategyTarget.getHost + val port = waitStrategyTarget.getMappedPort(ToxiproxyContainer.httpApiPort) + + logger.debug(s"[TOXIPROXY_WAIT] Waiting for Toxiproxy API at $host:$port") + + Unreliables.retryUntilSuccess( + startupTimeout.toSeconds.toInt, + TimeUnit.SECONDS, + () => { + try { + val client = new ToxiproxyClient(host, port) + client.getProxies // Simple API call to check readiness + logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API is ready at $host:$port") + true + } catch { + case e: Exception => + logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API not ready yet: ${e.getMessage}") + throw e } - - val proxyUpstream = s"$innerContainerIp:$innerServicePort" - val proxyListen = s"0.0.0.0:$proxiedPort" - - logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (container IP)") - toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) - logger.debug(s"[TOXIPROXY] Proxy created successfully") - - true - } catch { - case ex: Throwable => - logger.debug("Toxic Proxy is not ready", ex) - false } - } + ) } - private val httpApiPort = 8474 + override def withStartupTimeout(startupTimeout: Duration): WaitStrategy = { + this.startupTimeout = startupTimeout + this + } +} + +object ToxiproxyContainer { + private[containers] val httpApiPort = 8474 val proxiedPort = 5000 } \ No newline at end of file From e73d89172b15c5b6dad416e5704b19e915735b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 12:39:43 +0100 Subject: [PATCH 099/103] check --- .../UnboundidLdapUsersServiceNetworkRelatedTests.scala | 2 +- .../tech/beshu/ror/utils/containers/ToxiproxyContainer.scala | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/ldap/implementations/UnboundidLdapUsersServiceNetworkRelatedTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/ldap/implementations/UnboundidLdapUsersServiceNetworkRelatedTests.scala index eef311adb6..254be99b84 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/ldap/implementations/UnboundidLdapUsersServiceNetworkRelatedTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/blocks/definitions/ldap/implementations/UnboundidLdapUsersServiceNetworkRelatedTests.scala @@ -146,7 +146,7 @@ class UnboundidLdapUsersServiceNetworkRelatedTests val ldapConnectionConfig = createLdapConnectionConfig( poolName = ldapId, connectionMethod = ConnectionMethod.SingleServer( - LdapHost.from(s"ldap://localhost:${ldap1ContainerWithToxiproxy.innerContainerMappedPort}").get + LdapHost.from(s"ldap://${ldap1ContainerWithToxiproxy.containerHost}:${ldap1ContainerWithToxiproxy.innerContainerMappedPort}").get ) ) val result = for { diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index 38ac941df0..a878cd73c0 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -43,6 +43,8 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe private var innerContainerProxy: Option[Proxy] = None private var timeoutToxic: Option[toxic.Timeout] = None + def containerHost: String = container.getHost + def innerContainerMappedPort: Int = container.getMappedPort(proxiedPort) def disableNetwork(): Unit = { From 0e2d8f68dfa914cda6b65d5dbc7ea3cc73a825c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 12:55:29 +0100 Subject: [PATCH 100/103] check --- ...erverDiscoveryCheckYamlLoadedAccessControlTests.scala | 9 +++++++-- .../decoders/definitions/LdapServicesSettingsTests.scala | 2 +- .../beshu/ror/utils/containers/DnsServerContainer.scala | 2 ++ .../ror/utils/containers/LdapWithDnsContainer.scala | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala b/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala index a2876f08a6..bc2e5f13d6 100644 --- a/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala +++ b/core/src/test/scala/tech/beshu/ror/integration/LdapServerDiscoveryCheckYamlLoadedAccessControlTests.scala @@ -40,7 +40,12 @@ class LdapServerDiscoveryCheckYamlLoadedAccessControlTests override val container: Container = doNotCreateOnWindows(new LdapWithDnsContainer("LDAP1", "test_example.ldif")) - private lazy val ldapPort = container match { + private lazy val dnsHost = container match { + case ldap: LdapWithDnsContainer => ldap.dnsHost + case _ => "localhost" // Just some random value - this test suite is ignored on Windows and the container is not started. + } + + private lazy val dnsPort = container match { case ldap: LdapWithDnsContainer => ldap.dnsPort case _ => 1234 // Just some random value - this test suite is ignored on Windows and the container is not started. But we still have to define port - required by configuration below. } @@ -56,7 +61,7 @@ class LdapServerDiscoveryCheckYamlLoadedAccessControlTests | ldaps: | - name: ldap1 | server_discovery: - | dns_url: "dns://localhost:$ldapPort" + | dns_url: "dns://$dnsHost:$dnsPort" | ha: ROUND_ROBIN | ssl_enabled: false # default true | ssl_trust_all_certs: true # default false diff --git a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala index 476ec994b0..2931d31436 100644 --- a/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala +++ b/core/src/test/scala/tech/beshu/ror/unit/acl/factory/decoders/definitions/LdapServicesSettingsTests.scala @@ -1117,7 +1117,7 @@ class LdapServicesSettingsTests private(ldapConnectionPoolProvider: UnboundidLda | ldaps: | - name: ldap1 | server_discovery: - | dns_url: "dns://localhost:${ldapWithDnsContainer.dnsPort}" + | dns_url: "dns://${ldapWithDnsContainer.dnsHost}:${ldapWithDnsContainer.dnsPort}" | ttl: "3 hours" | ssl_enabled: false | ssl_trust_all_certs: true diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala index 08f45bdb00..453ce1aaae 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala @@ -47,6 +47,8 @@ class DnsServerContainer(srvServicePort: Int) cmd.withPortBindings(ports) } + def dnsHost: String = this.containerIpAddress + def dnsPort: Int = { // This is hack to obtain mapping of UDP port as testcontainers doesn't allow explicit mapping of UDP ports, // although it is mapping each port exposed by container(even UDP). diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala index 24c8c8f69d..c5d1c84628 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala @@ -26,6 +26,8 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) private var dnsContainer: Option[DnsServerContainer] = None + def dnsHost: String = dnsContainer.getOrElse(throw new Exception("DNS container hasn't been started yet")).dnsHost + def dnsPort: Int = dnsContainer.getOrElse(throw new Exception("DNS container hasn't been started yet")).dnsPort override def start(): Unit = { From 8f8948106d587a8263e1295fd9e5443e0c4d3d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 13:13:15 +0100 Subject: [PATCH 101/103] check --- .../tech/beshu/ror/utils/containers/DnsServerContainer.scala | 4 ++-- .../beshu/ror/utils/containers/LdapWithDnsContainer.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala index 453ce1aaae..b3d76924fd 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/DnsServerContainer.scala @@ -24,7 +24,7 @@ import scala.annotation.nowarn import scala.jdk.CollectionConverters.* @nowarn("cat=deprecation") -class DnsServerContainer(srvServicePort: Int) +class DnsServerContainer(srvServiceHost: String, srvServicePort: Int) extends GenericContainer( dockerImage = new ImageFromDockerfile() .withFileFromClasspath("Dockerfile", "coredns-image/Dockerfile") @@ -33,7 +33,7 @@ class DnsServerContainer(srvServicePort: Int) s""" |$$ORIGIN example.org. |@ 3600 IN SOA someorg.org. someorg.com. (2017042745 7200 3600 1209600 3600) - |_ldap._tcp. 86400 IN SRV 10 60 $srvServicePort localhost. + |_ldap._tcp. 86400 IN SRV 10 60 $srvServicePort $srvServiceHost. |""".stripMargin), ) { diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala index c5d1c84628..ae46ba87ac 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/LdapWithDnsContainer.scala @@ -32,7 +32,7 @@ class LdapWithDnsContainer(name: String, ldapInitScript: InitScriptSource) override def start(): Unit = { ldapContainer.start() - dnsContainer = Option(new DnsServerContainer(ldapContainer.ldapPort)) + dnsContainer = Option(new DnsServerContainer(ldapContainer.ldapHost, ldapContainer.ldapPort)) dnsContainer.foreach(_.start()) } From 6691b7ab8e6b371b8bfa2ae63f599f1c819ca137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 13:42:28 +0100 Subject: [PATCH 102/103] clean up --- .../utils/containers/ToxiproxyContainer.scala | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala index a878cd73c0..ad682ca0b3 100644 --- a/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala +++ b/tests-utils/src/main/scala/tech/beshu/ror/utils/containers/ToxiproxyContainer.scala @@ -20,13 +20,14 @@ import com.dimafeng.testcontainers.{GenericContainer, SingleContainer} import com.typesafe.scalalogging.LazyLogging import eu.rekawek.toxiproxy.model.{ToxicDirection, toxic} import eu.rekawek.toxiproxy.{Proxy, ToxiproxyClient} -import org.rnorth.ducttape.unreliables.Unreliables +import monix.eval.Task +import monix.execution.Scheduler.Implicits.global import org.testcontainers.containers.Network import org.testcontainers.containers.wait.strategy.{WaitStrategy, WaitStrategyTarget} import tech.beshu.ror.utils.containers.ToxiproxyContainer.{httpApiPort, proxiedPort} +import tech.beshu.ror.utils.misc.ScalaUtils.* import java.time.Duration -import java.util.concurrent.TimeUnit import scala.concurrent.duration.* import scala.language.postfixOps @@ -44,7 +45,7 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe private var timeoutToxic: Option[toxic.Timeout] = None def containerHost: String = container.getHost - + def innerContainerMappedPort: Int = container.getMappedPort(proxiedPort) def disableNetwork(): Unit = { @@ -69,62 +70,67 @@ class ToxiproxyContainer[T <: SingleContainer[_]](val innerContainer: T, innerSe override def start(): Unit = { innerContainer.start() super.start() - + + innerContainerProxy = Some(createProxy()) + } + + override def stop(): Unit = { + innerContainer.stop() + super.stop() + } + + private def createProxy() = { // Create proxy AFTER both containers are fully started // Fetch fresh container info to get the correct IP address val dockerClient = container.getDockerClient val freshContainerInfo = dockerClient.inspectContainerCmd(innerContainer.containerId).exec() val innerNetworks = freshContainerInfo.getNetworkSettings.getNetworks - - val innerContainerIp = if (innerNetworks.isEmpty) { - innerContainer.containerInfo.getConfig.getHostName - } else { - innerNetworks.values().iterator().next().getIpAddress - } - + + val innerContainerIp = + if (innerNetworks.isEmpty) innerContainer.containerInfo.getConfig.getHostName + else innerNetworks.values().iterator().next().getIpAddress + val proxyUpstream = s"$innerContainerIp:$innerServicePort" val proxyListen = s"0.0.0.0:$proxiedPort" - + logger.debug(s"[TOXIPROXY] Creating proxy: listen=$proxyListen, upstream=$proxyUpstream (container IP)") val toxiproxyClient = new ToxiproxyClient(container.getHost, container.getMappedPort(httpApiPort)) val proxy = toxiproxyClient.createProxy("proxy", proxyListen, proxyUpstream) logger.debug(s"[TOXIPROXY] Proxy created successfully") - - innerContainerProxy = Some(proxy) - } - override def stop(): Unit = { - innerContainer.stop() - super.stop() + proxy } - } private class ToxiproxyApiWaitStrategy extends WaitStrategy with LazyLogging { + private var startupTimeout: Duration = Duration.ofSeconds(60) override def waitUntilReady(waitStrategyTarget: WaitStrategyTarget): Unit = { val host = waitStrategyTarget.getHost val port = waitStrategyTarget.getMappedPort(ToxiproxyContainer.httpApiPort) - + logger.debug(s"[TOXIPROXY_WAIT] Waiting for Toxiproxy API at $host:$port") - - Unreliables.retryUntilSuccess( - startupTimeout.toSeconds.toInt, - TimeUnit.SECONDS, - () => { - try { - val client = new ToxiproxyClient(host, port) - client.getProxies // Simple API call to check readiness - logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API is ready at $host:$port") - true - } catch { - case e: Exception => - logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API not ready yet: ${e.getMessage}") - throw e - } - } - ) + + retryBackoff( + source = Task.delay(isToxiproxyReady(host, port)), + maxRetries = 150, + firstDelay = 1 second, + backOffScaler = 1 + ).runSyncUnsafe(startupTimeout) + } + + private def isToxiproxyReady(host: String, port: Int): Boolean = { + try { + val client = new ToxiproxyClient(host, port) + client.getProxies + logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API is ready at $host:$port") + true + } catch { + case e: Exception => + logger.debug(s"[TOXIPROXY_WAIT] Toxiproxy API not ready yet: ${e.getMessage}") + false + } } override def withStartupTimeout(startupTimeout: Duration): WaitStrategy = { From 5b7c284c46ec95975325710eca598852e3450092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ko=C5=82odziejczyk?= Date: Wed, 17 Dec 2025 14:16:14 +0100 Subject: [PATCH 103/103] clean up --- .../scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala index 3ab3e8df80..cba9edf674 100644 --- a/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala +++ b/core/src/main/scala/tech/beshu/ror/boot/RorSettingsAutoReloader.scala @@ -94,7 +94,7 @@ class EnabledRorSettingsAutoReloader(reloadInterval: PositiveFiniteDuration, reloadResults.foreach(logSettingsReloadResult) scheduleNextIfNotStopping(interval, reloadTask) case Left(ex) => - logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: error", ex) + logger.error(s"[CLUSTERWIDE SETTINGS][${requestId.show}] Checking index settings failed: ${ex.getMessage}") scheduleNextIfNotStopping(interval, reloadTask) } }