From e55809c0219be0898138c436d82ceba212b92df9 Mon Sep 17 00:00:00 2001 From: Filip Krzywka Date: Fri, 5 Apr 2019 11:10:46 +0200 Subject: Flatten configuration structure Change-Id: I9a5a53f3c4cf0973d071f2bc6962016b5613972d Issue-ID: DCAEGEN2-710 Signed-off-by: Filip Krzywka --- development/configuration/base.json | 26 +-- development/configuration/local.json | 28 ++- .../veshv/config/impl/CbsConfigurationProvider.kt | 2 +- .../veshv/config/impl/ConfigurationMerger.kt | 70 ++------ .../veshv/config/impl/ConfigurationValidator.kt | 57 ++++--- .../veshv/config/impl/FileConfigurationReader.kt | 2 - .../config/impl/gsonadapters/SecurityAdapter.kt | 68 -------- .../veshv/config/impl/partial_configuration.kt | 40 +++-- .../config/impl/CbsConfigurationProviderTest.kt | 2 +- .../veshv/config/impl/ConfigurationMergerTest.kt | 28 ++- .../config/impl/ConfigurationValidatorTest.kt | 187 ++++++++++++--------- .../config/impl/FileConfigurationReaderTest.kt | 48 +++--- .../impl/gsonadapters/SecurityAdapterTest.kt | 135 --------------- .../src/test/resources/sampleConfig.json | 31 ++-- .../hv-collector-main/src/main/docker/base.json | 17 +- 15 files changed, 249 insertions(+), 492 deletions(-) delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt delete mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt diff --git a/development/configuration/base.json b/development/configuration/base.json index c89a8288..13c4ea19 100644 --- a/development/configuration/base.json +++ b/development/configuration/base.json @@ -1,20 +1,12 @@ { "logLevel": "DEBUG", - "server": { - "listenPort": 6061, - "idleTimeoutSec": 60, - "maxPayloadSizeBytes": 1048576 - }, - "cbs": { - "firstRequestDelaySec": 10, - "requestIntervalSec": 5 - }, - "security": { - "keys": { - "keyStoreFile": "/etc/ves-hv/ssl/server.p12", - "keyStorePassword": "onaponap", - "trustStoreFile": "/etc/ves-hv/ssl/trust.p12", - "trustStorePassword": "onaponap" - } - } + "server.listenPort": 6061, + "server.idleTimeoutSec": 60, + "server.maxPayloadSizeBytes": 1048576, + "cbs.firstRequestDelaySec": 10, + "cbs.requestIntervalSec": 5, + "security.keys.keyStoreFile": "/etc/ves-hv/ssl/server.p12", + "security.keys.keyStorePassword": "onaponap", + "security.keys.trustStoreFile": "/etc/ves-hv/ssl/trust.p12", + "security.keys.trustStorePassword": "onaponap" } \ No newline at end of file diff --git a/development/configuration/local.json b/development/configuration/local.json index a1a8b533..79abe03b 100644 --- a/development/configuration/local.json +++ b/development/configuration/local.json @@ -1,20 +1,12 @@ { "logLevel": "DEBUG", - "server": { - "listenPort": 8061, - "idleTimeoutSec": 60, - "maxPayloadSizeBytes": 1048576 - }, - "cbs": { - "firstRequestDelaySec": 10, - "requestIntervalSec": 5 - }, - "security": { - "keys": { - "keyStoreFile": "development/ssl/server.p12", - "keyStorePassword": "onaponap", - "trustStoreFile": "development/ssl/trust.p12", - "trustStorePassword": "onaponap" - } - } -} \ No newline at end of file + "server.listenPort": 8061, + "server.idleTimeoutSec": 60, + "server.maxPayloadSizeBytes": 1048576, + "cbs.firstRequestDelaySec": 10, + "cbs.requestIntervalSec": 5, + "security.keys.keyStoreFile": "development/ssl/server.p12", + "security.keys.keyStorePassword": "onaponap", + "security.keys.trustStoreFile": "development/ssl/trust.p12", + "security.keys.trustStorePassword": "onaponap" +} diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProvider.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProvider.kt index 2038c31a..b6462936 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProvider.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProvider.kt @@ -95,7 +95,7 @@ internal class CbsConfigurationProvider(private val cbsClientMono: Mono = try { val routes = DataStreams.namedSinks(configuration) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMerger.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMerger.kt index 63d590a2..8e6bafc4 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMerger.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMerger.kt @@ -20,12 +20,12 @@ package org.onap.dcae.collectors.veshv.config.impl -import arrow.core.None import arrow.core.Option import arrow.core.Some import arrow.core.getOrElse import arrow.core.toOption -import org.onap.dcae.collectors.veshv.utils.logging.LogLevel +import kotlin.reflect.KProperty0 +import kotlin.reflect.KProperty1 /** * @author Pawel Biniek @@ -34,62 +34,28 @@ import org.onap.dcae.collectors.veshv.utils.logging.LogLevel internal class ConfigurationMerger { fun merge(base: PartialConfiguration, update: PartialConfiguration): PartialConfiguration = PartialConfiguration( - mergeServerConfig(base.server, update.server), - mergeCbsConfig(base.cbs, update.cbs), - mergeSecurityConfig(base.security, update.security), - mergeCollectorConfig(base.collector, update.collector), - mergeLogLevel(base.logLevel, update.logLevel) - ) - - - private fun mergeServerConfig(baseOption: Option, - updateOption: Option) = - applyUpdate(baseOption, updateOption) { base, update -> - PartialServerConfig( - base.listenPort.updateToGivenOrNone(update.listenPort), - base.idleTimeoutSec.updateToGivenOrNone(update.idleTimeoutSec), - base.maxPayloadSizeBytes.updateToGivenOrNone(update.maxPayloadSizeBytes) - ) - } + listenPort = base.listenPort.updateToGivenOrNone(update.listenPort), + idleTimeoutSec = base.idleTimeoutSec.updateToGivenOrNone(update.idleTimeoutSec), + maxPayloadSizeBytes = base.maxPayloadSizeBytes.updateToGivenOrNone(update.maxPayloadSizeBytes), + firstRequestDelaySec = base.firstRequestDelaySec.updateToGivenOrNone(update.firstRequestDelaySec), + requestIntervalSec = base.requestIntervalSec.updateToGivenOrNone(update.requestIntervalSec), - private fun mergeCbsConfig(baseOption: Option, - updateOption: Option) = - applyUpdate(baseOption, updateOption) { base, update -> - PartialCbsConfig( - base.firstRequestDelaySec.updateToGivenOrNone(update.firstRequestDelaySec), - base.requestIntervalSec.updateToGivenOrNone(update.requestIntervalSec) - ) - } + sslDisable = base.sslDisable.updateToGivenOrNone(update.sslDisable), + keyStoreFile = base.keyStoreFile.updateToGivenOrNone(update.keyStoreFile), + keyStorePassword = base.keyStorePassword.updateToGivenOrNone(update.keyStorePassword), + trustStoreFile = base.trustStoreFile.updateToGivenOrNone(update.trustStoreFile), + trustStorePassword = base.trustStorePassword.updateToGivenOrNone(update.trustStorePassword), - private fun mergeSecurityConfig(baseOption: Option, - updateOption: Option) = - applyUpdate(baseOption, updateOption) { base, update -> - PartialSecurityConfig( - base.keys.updateToGivenOrNone(update.keys) - ) - } + routing = base.routing.updateToGivenOrNone(update.routing), - private fun mergeCollectorConfig(baseOption: Option, - updateOption: Option) = - applyUpdate(baseOption, updateOption) { base, update -> - PartialCollectorConfig( - base.routing.updateToGivenOrNone(update.routing) - ) - } + logLevel = base.logLevel.updateToGivenOrNone(update.logLevel) + ) + private fun Option.updateToGivenOrNone(update: Option) = + update.getOrElse(this::orNull).toOption() - private fun mergeLogLevel(base: Option, update: Option) = - base.updateToGivenOrNone(update) } -private fun applyUpdate(base: Option, update: Option, overrider: (base: T, update: T) -> T) = - when { - base is Some && update is Some -> overrider(base.t, update.t).toOption() - base is Some && update is None -> base - base is None && update is Some -> update - else -> None - } -private fun Option.updateToGivenOrNone(update: Option) = - update.getOrElse(this::orNull).toOption() + diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt index 407fd745..cfcc7d76 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt @@ -19,9 +19,9 @@ */ package org.onap.dcae.collectors.veshv.config.impl -import arrow.core.Either import arrow.core.None import arrow.core.Option +import arrow.core.Some import arrow.core.getOrElse import org.onap.dcae.collectors.veshv.config.api.model.CbsConfiguration import org.onap.dcae.collectors.veshv.config.api.model.CollectorConfiguration @@ -35,6 +35,7 @@ import org.onap.dcae.collectors.veshv.utils.arrow.mapBinding import org.onap.dcae.collectors.veshv.utils.arrow.doOnEmpty import org.onap.dcae.collectors.veshv.utils.logging.LogLevel import org.onap.dcae.collectors.veshv.utils.logging.Logger +import java.io.File /** * @author Jakub Dudycz @@ -55,7 +56,7 @@ internal class ConfigurationValidator { .doOnEmpty { logger.debug { "Cannot bind cbs configuration" } } .bind() - val securityConfiguration = validatedSecurityConfiguration(partialConfig) + val securityConfiguration = determineSecurityConfiguration(partialConfig) .doOnEmpty { logger.debug { "Cannot bind security configuration" } } .bind() @@ -85,39 +86,47 @@ internal class ConfigurationValidator { private fun validatedServerConfiguration(partial: PartialConfiguration) = partial.mapBinding { - partial.server.bind().let { - ServerConfiguration( - it.listenPort.bind(), - it.idleTimeoutSec.bind(), - it.maxPayloadSizeBytes.bind() - ) - } + ServerConfiguration( + it.listenPort.bind(), + it.idleTimeoutSec.bind(), + it.maxPayloadSizeBytes.bind() + ) } internal fun validatedCbsConfiguration(partial: PartialConfiguration) = partial.mapBinding { - it.cbs.bind().let { - CbsConfiguration( - it.firstRequestDelaySec.bind(), - it.requestIntervalSec.bind() - ) - } + CbsConfiguration( + it.firstRequestDelaySec.bind(), + it.requestIntervalSec.bind() + ) } - private fun validatedSecurityConfiguration(partial: PartialConfiguration) = - partial.mapBinding { - it.security.bind().let { - SecurityConfiguration(it.keys.map(SecurityKeysPaths::asImmutableSecurityKeys)) + private fun determineSecurityConfiguration(partial: PartialConfiguration) = + partial.sslDisable.fold({ createSecurityConfiguration(partial) }, { sslDisabled -> + if (sslDisabled) { + Some(SecurityConfiguration(None)) + } else { + createSecurityConfiguration(partial) } + }) + + private fun createSecurityConfiguration(partial: PartialConfiguration): Option = + partial.mapBinding { + SecurityConfiguration( + Option.fromNullable(SecurityKeysPaths( + File(it.keyStoreFile.bind()).toPath(), + it.keyStorePassword.bind(), + File(it.trustStoreFile.bind()).toPath(), + it.trustStorePassword.bind() + ).asImmutableSecurityKeys()) + ) } private fun validatedCollectorConfig(partial: PartialConfiguration) = partial.mapBinding { - partial.collector.bind().let { - CollectorConfiguration( - it.routing.bind() - ) - } + CollectorConfiguration( + it.routing.bind() + ) } companion object { diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt index f6ae5bec..104ca78c 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReader.kt @@ -23,7 +23,6 @@ import arrow.core.Option import com.google.gson.GsonBuilder import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.DurationOfSecondsAdapter import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.OptionAdapter -import org.onap.dcae.collectors.veshv.config.impl.gsonadapters.SecurityAdapter import org.onap.dcae.collectors.veshv.utils.logging.Logger import java.io.Reader @@ -36,7 +35,6 @@ import java.time.Duration internal class FileConfigurationReader { private val gson = GsonBuilder() .registerTypeAdapter(Option::class.java, OptionAdapter()) - .registerTypeAdapter(PartialSecurityConfig::class.java, SecurityAdapter()) .registerTypeAdapter(Duration::class.java, DurationOfSecondsAdapter()) .create() diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt deleted file mode 100644 index bc8cf51c..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2019 NOKIA - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.dcae.collectors.veshv.config.impl.gsonadapters - -import arrow.core.Option -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import com.google.gson.JsonObject -import org.onap.dcae.collectors.veshv.config.impl.PartialSecurityConfig -import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths -import java.io.File -import java.lang.reflect.Type - -/** - * @author Pawel Biniek - * @since March 2019 - */ -internal class SecurityAdapter : JsonDeserializer { - - override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext?) = - json.asJsonObject.let { security -> - if (security.entrySet().isEmpty() || hasSslDisableSet(security)) { - PartialSecurityConfig(Option.empty()) - } else { - PartialSecurityConfig(Option.just(security.securityKeys(::asImmutableSecurityKeys))) - } - } - - private fun hasSslDisableSet(security: JsonObject) = - security.has(SSL_DISABLE_KEY) && security[SSL_DISABLE_KEY].asBoolean - - private fun JsonObject.securityKeys(f: (JsonObject) -> SecurityKeysPaths) = f(getAsJsonObject(KEYS_OBJECT_KEY)) - - private fun asImmutableSecurityKeys(keys: JsonObject) = SecurityKeysPaths( - File(keys[KEY_STORE_FILE_KEY].asString).toPath(), - keys[KEY_STORE_PASSWORD_KEY].asString, - File(keys[TRUST_STORE_FILE_KEY].asString).toPath(), - keys[TRUST_STORE_PASSWORD_KEY].asString - ) - - companion object { - private val SSL_DISABLE_KEY = "sslDisable" - private val KEYS_OBJECT_KEY = "keys" - private val KEY_STORE_FILE_KEY = "keyStoreFile" - private val KEY_STORE_PASSWORD_KEY = "keyStorePassword" - private val TRUST_STORE_FILE_KEY = "trustStoreFile" - private val TRUST_STORE_PASSWORD_KEY = "trustStorePassword" - } -} - diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt index 82cf533a..0be2572d 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt @@ -21,8 +21,8 @@ package org.onap.dcae.collectors.veshv.config.impl import arrow.core.None import arrow.core.Option +import com.google.gson.annotations.SerializedName import org.onap.dcae.collectors.veshv.config.api.model.Routing -import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import org.onap.dcae.collectors.veshv.utils.logging.LogLevel import java.time.Duration @@ -31,26 +31,32 @@ import java.time.Duration * @since February 2019 */ internal data class PartialConfiguration( - val server: Option = None, - val cbs: Option = None, - val security: Option = None, - val collector: Option = None, - val logLevel: Option = None -) - -internal data class PartialServerConfig( + @SerializedName("server.listenPort") val listenPort: Option = None, + @SerializedName("server.idleTimeoutSec") val idleTimeoutSec: Option = None, - val maxPayloadSizeBytes: Option = None -) + @SerializedName("server.maxPayloadSizeBytes") + val maxPayloadSizeBytes: Option = None, -internal data class PartialCbsConfig( + @SerializedName("cbs.firstRequestDelaySec") val firstRequestDelaySec: Option = None, - val requestIntervalSec: Option = None -) + @SerializedName("cbs.requestIntervalSec") + val requestIntervalSec: Option = None, + + @SerializedName("security.sslDisable") + val sslDisable: Option = None, + @SerializedName("security.keys.keyStoreFile") + val keyStoreFile: Option = None, + @SerializedName("security.keys.keyStorePassword") + val keyStorePassword: Option = None, + @SerializedName("security.keys.trustStoreFile") + val trustStoreFile: Option = None, + @SerializedName("security.keys.trustStorePassword") + val trustStorePassword: Option = None, -internal data class PartialSecurityConfig(val keys: Option = None) + @SerializedName("collector.routing") + val routing: Option = None, -internal data class PartialCollectorConfig( - val routing: Option = None + @SerializedName("logLevel") + val logLevel: Option = None ) diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProviderTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProviderTest.kt index 0cbc0e4a..d5fe588e 100644 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProviderTest.kt +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/CbsConfigurationProviderTest.kt @@ -78,7 +78,7 @@ internal object CbsConfigurationProviderTest : Spek({ StepVerifier.create(configProvider().take(1)) .consumeNextWith { - val routes = it.collector.orNull()!!.routing.orNull()!! + val routes = it.routing.orNull()!! val route1 = routes.elementAt(0) val route2 = routes.elementAt(1) val receivedSink1 = route1.sink diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMergerTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMergerTest.kt index d5b18e68..bc61b57d 100644 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMergerTest.kt +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationMergerTest.kt @@ -44,14 +44,14 @@ internal object ConfigurationMergerTest : Spek({ assertThat(result.logLevel).isEqualTo(Some(LogLevel.INFO)) } + val someListenPort = Some(45) it("merges single embedded parameter into empty config") { val actual = PartialConfiguration() - val serverConfig = PartialServerConfig(listenPort = Some(45)) - val diff = PartialConfiguration(server = Some(serverConfig)) + val diff = PartialConfiguration(listenPort = someListenPort) val result = ConfigurationMerger().merge(actual, diff) - assertThat(result.server).isEqualTo(Some(serverConfig)) + assertThat(result.listenPort).isEqualTo(someListenPort) } it("merges single parameter into full config") { @@ -69,16 +69,15 @@ internal object ConfigurationMergerTest : Spek({ val actual = FileConfigurationReader().loadConfig( InputStreamReader( FileConfigurationReaderTest.javaClass.getResourceAsStream("/sampleConfig.json")) as Reader) - val serverConfig = PartialServerConfig(listenPort = Some(45)) - val diff = PartialConfiguration(server = Some(serverConfig)) + val diff = PartialConfiguration(listenPort = someListenPort) val result = ConfigurationMerger().merge(actual, diff) - assertThat(result.server.orNull()?.listenPort).isEqualTo(serverConfig.listenPort) - assertThat(result.server.orNull()?.idleTimeoutSec?.isEmpty()).isFalse() - assertThat(result.server.orNull()?.idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) - assertThat(result.server.orNull()?.maxPayloadSizeBytes?.isEmpty()).isFalse() - assertThat(result.server.orNull()?.maxPayloadSizeBytes).isEqualTo(Some(512000)) + assertThat(result.listenPort).isEqualTo(someListenPort) + assertThat(result.idleTimeoutSec.isEmpty()).isFalse() + assertThat(result.idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) + assertThat(result.maxPayloadSizeBytes.isEmpty()).isFalse() + assertThat(result.maxPayloadSizeBytes).isEqualTo(Some(1048576)) } it("merges full config into single parameter") { @@ -90,12 +89,11 @@ internal object ConfigurationMergerTest : Spek({ val result = ConfigurationMerger().merge(actual, diff) assertThat(result.logLevel).isEqualTo(Some(LogLevel.ERROR)) - assertThat(result.server.isEmpty()).isFalse() - assertThat(result.server.orNull()?.maxPayloadSizeBytes).isEqualTo(Some(512000)) - assertThat(result.server.orNull()?.idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) + assertThat(result.maxPayloadSizeBytes).isEqualTo(Some(1048576)) + assertThat(result.idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) - assertThat(result.security.isEmpty()).isFalse() - assertThat(result.cbs.isEmpty()).isFalse() + assertThat(result.keyStoreFile.isEmpty()).isFalse() + assertThat(result.firstRequestDelaySec.isEmpty()).isFalse() } } }) diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt index 682bec5a..e43acfa3 100644 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt @@ -23,29 +23,26 @@ import arrow.core.None import arrow.core.Option import arrow.core.Some import arrow.core.getOrElse -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.fail -import org.assertj.core.api.ObjectAssert import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it import org.onap.dcae.collectors.veshv.config.api.model.Routing import org.onap.dcae.collectors.veshv.config.impl.ConfigurationValidator.Companion.DEFAULT_LOG_LEVEL -import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import org.onap.dcae.collectors.veshv.utils.logging.LogLevel import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys +import java.io.File import java.time.Duration + internal object ConfigurationValidatorTest : Spek({ describe("ConfigurationValidator") { val cut = ConfigurationValidator() describe("validating partial configuration with missing fields") { val config = PartialConfiguration( - Some(PartialServerConfig(listenPort = Some(1))) + listenPort = Some(1) ) it("should return ValidationError") { @@ -55,23 +52,8 @@ internal object ConfigurationValidatorTest : Spek({ } describe("validating configuration with empty log level") { - val config = PartialConfiguration( - Some(PartialServerConfig( - Some(1), - Some(Duration.ofSeconds(2)), - Some(3) - )), - Some(PartialCbsConfig( - Some(Duration.ofSeconds(5)), - Some(Duration.ofSeconds(3)) - )), - Some(PartialSecurityConfig( - Some(mock()) - )), - Some(PartialCollectorConfig( - someFromEmptyRouting - )), - None + val config = partialConfiguration( + logLevel = None ) it("should use default log level") { @@ -88,29 +70,19 @@ internal object ConfigurationValidatorTest : Spek({ } describe("validating complete configuration") { - val idleTimeoutSec = Duration.ofSeconds(10L) - val firstReqDelaySec = Duration.ofSeconds(10L) - val securityKeys = mock() - val immutableSecurityKeys = mock() - whenever(securityKeys.asImmutableSecurityKeys()).thenReturn(immutableSecurityKeys) - val config = PartialConfiguration( - Some(PartialServerConfig( - Some(1), - Some(idleTimeoutSec), - Some(2) - )), - Some(PartialCbsConfig( - Some(firstReqDelaySec), - Some(Duration.ofSeconds(3)) - )), - Some(PartialSecurityConfig( - Some(securityKeys) - )), - Some(PartialCollectorConfig( - someFromEmptyRouting - )), - Some(LogLevel.INFO) + listenPort = Some(defaultListenPort), + idleTimeoutSec = Some(defaultIdleTimeoutSec), + maxPayloadSizeBytes = Some(defaultMaxPayloadSizeBytes), + firstRequestDelaySec = Some(defaultFirstReqDelaySec), + requestIntervalSec = Some(defaultRequestIntervalSec), + sslDisable = Some(false), + keyStoreFile = Some(KEYSTORE), + keyStorePassword = Some(KEYSTORE_PASSWORD), + trustStoreFile = Some(TRUSTSTORE), + trustStorePassword = Some(TRUSTSTORE_PASSWORD), + routing = Some(emptyRouting), + logLevel = Some(LogLevel.TRACE) ) it("should create valid configuration") { @@ -120,46 +92,34 @@ internal object ConfigurationValidatorTest : Spek({ fail("Configuration should have been created successfully") }, { - assertThat(it.server.idleTimeout) - .isEqualTo(idleTimeoutSec) - - verify(securityKeys).asImmutableSecurityKeys() - assertThat(it.security.keys - .getOrElse { fail("Should be immutableSecurityKeys") }) - .isEqualTo(immutableSecurityKeys) - - assertThat(it.cbs.firstRequestDelay) - .isEqualTo(firstReqDelaySec) - - assertThat(it.collector.routing) - .isEqualTo(emptyRouting) + assertThat(it.server.listenPort).isEqualTo(defaultListenPort) + assertThat(it.server.idleTimeout).isEqualTo(defaultIdleTimeoutSec) + assertThat(it.server.maxPayloadSizeBytes).isEqualTo(defaultMaxPayloadSizeBytes) + + val securityKeys = it.security.keys + .getOrElse { fail("Should be immutableSecurityKeys") } as SecurityKeys + assertThat(securityKeys.keyStore().path()).isEqualTo(File(KEYSTORE).toPath()) + assertThat(securityKeys.trustStore().path()).isEqualTo(File(TRUSTSTORE).toPath()) + securityKeys.keyStorePassword().use { assertThat(it).isEqualTo(KEYSTORE_PASSWORD.toCharArray()) } + securityKeys.trustStorePassword().use { assertThat(it).isEqualTo(TRUSTSTORE_PASSWORD.toCharArray()) } + + assertThat(it.cbs.firstRequestDelay).isEqualTo(defaultFirstReqDelaySec) + assertThat(it.cbs.requestInterval).isEqualTo(defaultRequestIntervalSec) + + assertThat(it.collector.routing).isEqualTo(emptyRouting) + assertThat(it.logLevel).isEqualTo(LogLevel.TRACE) } ) } } describe("validating configuration with security disabled") { - val idleTimeoutSec = Duration.ofSeconds(10) - val firstReqDelaySec = Duration.ofSeconds(10) - val missingSecurityKeys: Option = None - - val config = PartialConfiguration( - Some(PartialServerConfig( - Some(1), - Some(idleTimeoutSec), - Some(2) - )), - Some(PartialCbsConfig( - Some(firstReqDelaySec), - Some(Duration.ofSeconds(3)) - )), - Some(PartialSecurityConfig( - missingSecurityKeys - )), - Some(PartialCollectorConfig( - someFromEmptyRouting - )), - Some(LogLevel.INFO) + val config = partialConfiguration( + sslDisable = Some(true), + keyStoreFile = Some(""), + keyStorePassword = Some(""), + trustStoreFile = Some(""), + trustStorePassword = Some("") ) it("should create valid configuration") { @@ -170,13 +130,13 @@ internal object ConfigurationValidatorTest : Spek({ }, { assertThat(it.server.idleTimeout) - .isEqualTo(idleTimeoutSec) + .isEqualTo(defaultIdleTimeoutSec) assertThat(it.security.keys) - .isEqualTo(missingSecurityKeys) + .isEqualTo(None) assertThat(it.cbs.firstRequestDelay) - .isEqualTo(firstReqDelaySec) + .isEqualTo(defaultFirstReqDelaySec) assertThat(it.collector.routing) .isEqualTo(emptyRouting) @@ -185,8 +145,69 @@ internal object ConfigurationValidatorTest : Spek({ } } + describe("validating configuration with ssl disable missing") { + val config = partialConfiguration( + sslDisable = None + ) + + it("should create valid configuration with ssl enabled") { + val result = cut.validate(config) + result.fold( + { + fail("Configuration should have been created successfully but was $it") + }, + { + val securityKeys = it.security.keys + .getOrElse { fail("Should be immutableSecurityKeys") } as SecurityKeys + assertThat(securityKeys.keyStore().path()).isEqualTo(File(KEYSTORE).toPath()) + assertThat(securityKeys.trustStore().path()).isEqualTo(File(TRUSTSTORE).toPath()) + securityKeys.keyStorePassword().use { assertThat(it).isEqualTo(KEYSTORE_PASSWORD.toCharArray()) } + securityKeys.trustStorePassword().use { assertThat(it).isEqualTo(TRUSTSTORE_PASSWORD.toCharArray()) } + } + ) + } + } + } }) +private fun partialConfiguration(listenPort: Option = Some(defaultListenPort), + idleTimeoutSec: Option = Some(defaultIdleTimeoutSec), + maxPayloadSizeBytes: Option = Some(defaultMaxPayloadSizeBytes), + firstReqDelaySec: Option = Some(defaultFirstReqDelaySec), + requestIntervalSec: Option = Some(defaultRequestIntervalSec), + sslDisable: Option = Some(false), + keyStoreFile: Option = Some(KEYSTORE), + keyStorePassword: Option = Some(KEYSTORE_PASSWORD), + trustStoreFile: Option = Some(TRUSTSTORE), + trustStorePassword: Option = Some(TRUSTSTORE_PASSWORD), + routing: Option = Some(emptyRouting), + logLevel: Option = Some(LogLevel.INFO) +) = + PartialConfiguration( + listenPort = listenPort, + idleTimeoutSec = idleTimeoutSec, + maxPayloadSizeBytes = maxPayloadSizeBytes, + firstRequestDelaySec = firstReqDelaySec, + requestIntervalSec = requestIntervalSec, + sslDisable = sslDisable, + keyStoreFile = keyStoreFile, + keyStorePassword = keyStorePassword, + trustStoreFile = trustStoreFile, + trustStorePassword = trustStorePassword, + routing = routing, + logLevel = logLevel + ) + +val defaultListenPort = 1234 +val defaultRequestIntervalSec = Duration.ofSeconds(3) +val defaultMaxPayloadSizeBytes = 2 +val defaultIdleTimeoutSec = Duration.ofSeconds(10L) +val defaultFirstReqDelaySec = Duration.ofSeconds(10L) + +val KEYSTORE = "test.ks.pkcs12" +val KEYSTORE_PASSWORD = "changeMe" +val TRUSTSTORE = "trust.ks.pkcs12" +val TRUSTSTORE_PASSWORD = "changeMeToo" + val emptyRouting: Routing = emptyList() -val someFromEmptyRouting = Some(emptyRouting) diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt index 4e35bfb3..b4683458 100644 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt @@ -20,6 +20,7 @@ package org.onap.dcae.collectors.veshv.config.impl import arrow.core.Some +import arrow.core.getOrElse import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe @@ -27,8 +28,8 @@ import org.jetbrains.spek.api.dsl.it import org.onap.dcae.collectors.veshv.tests.utils.resourceAsStream import org.onap.dcae.collectors.veshv.utils.logging.LogLevel import java.io.StringReader -import java.net.InetSocketAddress import java.time.Duration +import kotlin.test.fail /** * @author Pawel Biniek @@ -46,29 +47,24 @@ internal object FileConfigurationReaderTest : Spek({ assertThat(config.logLevel).isEqualTo(Some(LogLevel.ERROR)) } - it("parses simple structure") { + it("parses simple structure and creates correct objects") { val input = """{ - "server" : { - "healthCheckApiPort" : 12002, - "listenPort" : 12003 + "server.listenPort" : 12003, + "cbs.firstRequestDelaySec": 10 } - } - """.trimIndent() + """.trimIndent() val config = cut.loadConfig(StringReader(input)) - assertThat(config.server.nonEmpty()).isTrue() - assertThat(config.server.orNull()?.listenPort).isEqualTo(Some(12003)) + assertThat(config.listenPort).isEqualTo(Some(12003)) + assertThat(config.firstRequestDelaySec).isEqualTo(Some(Duration.ofSeconds(10))) } it("parses disabled security configuration") { val input = """{ - "security": { - } + "security.sslDisable": true }""".trimIndent() val config = cut.loadConfig(StringReader(input)) - assertThat(config.security.nonEmpty()).isTrue() - val security = config.security.orNull() as PartialSecurityConfig - assertThat(security.keys.nonEmpty()).isFalse() + assertThat(config.sslDisable.getOrElse { fail("Should be Some") }).isTrue() } it("parses invalid log level string to empty option") { @@ -89,22 +85,18 @@ internal object FileConfigurationReaderTest : Spek({ assertThat(config).isNotNull assertThat(config.logLevel).isEqualTo(Some(LogLevel.ERROR)) - assertThat(config.security.nonEmpty()).isTrue() - val security = config.security.orNull() as PartialSecurityConfig - assertThat(security.keys.nonEmpty()).isTrue() + assertThat(config.listenPort).isEqualTo(Some(6000)) + assertThat(config.idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) + assertThat(config.maxPayloadSizeBytes).isEqualTo(Some(1048576)) - assertThat(config.cbs.nonEmpty()).isTrue() - val cbs = config.cbs.orNull() as PartialCbsConfig - assertThat(cbs.firstRequestDelaySec).isEqualTo(Some(Duration.ofSeconds(7))) - assertThat(cbs.requestIntervalSec).isEqualTo(Some(Duration.ofSeconds(900))) + assertThat(config.firstRequestDelaySec).isEqualTo(Some(Duration.ofSeconds(7))) + assertThat(config.requestIntervalSec).isEqualTo(Some(Duration.ofSeconds(900))) - assertThat(config.server.nonEmpty()).isTrue() - val server = config.server.orNull() as PartialServerConfig - server.run { - assertThat(idleTimeoutSec).isEqualTo(Some(Duration.ofSeconds(1200))) - assertThat(listenPort).isEqualTo(Some(6000)) - assertThat(maxPayloadSizeBytes).isEqualTo(Some(512000)) - } + assertThat(config.sslDisable).isEqualTo(Some(false)) + assertThat(config.keyStoreFile).isEqualTo(Some("test.ks.pkcs12")) + assertThat(config.keyStorePassword).isEqualTo(Some("changeMe")) + assertThat(config.trustStoreFile).isEqualTo(Some("trust.ks.pkcs12")) + assertThat(config.trustStorePassword).isEqualTo(Some("changeMeToo")) } } } diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt deleted file mode 100644 index a466896b..00000000 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapterTest.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2019 NOKIA - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.dcae.collectors.veshv.config.impl.gsonadapters - -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonParser -import com.google.gson.reflect.TypeToken -import com.nhaarman.mockitokotlin2.mock -import org.assertj.core.api.Assertions -import org.jetbrains.spek.api.Spek -import org.jetbrains.spek.api.dsl.describe -import org.jetbrains.spek.api.dsl.given -import org.jetbrains.spek.api.dsl.it - -internal object SecurityAdapterTest : Spek({ - - describe("deserialization") { - val gson = JsonParser() - val context = mock() - val someType = TypeToken.get(SecurityAdapter::class.java).type - - val cut = SecurityAdapter() - - given("empty security object") { - val json = gson.parse("{}") - - it("should parse json to security configuration without keys") { - val deserialized = cut.deserialize(json, someType, context) - - Assertions.assertThat(deserialized.keys.isEmpty()).isTrue() - } - } - - given("valid security object with ssl disabled") { - - given("security keys missing") { - val json = gson.parse(SECURITY_WITH_SSL_DISABLED_AND_KEYS_MISSING) - - it("should parse json to security configuration without keys") { - val deserialized = cut.deserialize(json, someType, context) - - Assertions.assertThat(deserialized.keys.isEmpty()).isTrue() - } - } - - given("security keys provided") { - val json = gson.parse(SECURITY_WITH_SSL_DISABLED_AND_KEYS_PROVIDED) - - it("should parse json to security configuration without keys") { - val deserialized = cut.deserialize(json, someType, context) - - Assertions.assertThat(deserialized.keys.isEmpty()).isTrue() - } - } - } - - given("valid security object with missing sslDisable key") { - val json = gson.parse(MISSING_SSL_DISABLE_ENTRY) - - it("should return parse json to security configuration") { - val deserialized = cut.deserialize(json, someType, context) - - Assertions.assertThat(deserialized.keys.isDefined()).isTrue() - } - } - - given("valid security object with ssl enabled") { - val json = gson.parse(VALID_SECURITY_WITH_SSL_ENABLED) - - it("should return parse json to security configuration") { - val deserialized = cut.deserialize(json, someType, context) - - Assertions.assertThat(deserialized.keys.isDefined()).isTrue() - } - } - } -}) - -val SECURITY_WITH_SSL_DISABLED_AND_KEYS_MISSING = """ -{ - "sslDisable": true -} -""" - -val SECURITY_WITH_SSL_DISABLED_AND_KEYS_PROVIDED = """ -{ - "sslDisable": true, - "keys": { - "keyStoreFile": "test.ks.pkcs12", - "keyStorePassword": "changeMe", - "trustStoreFile": "trust.ks.pkcs12", - "trustStorePassword": "changeMeToo" - } -} -""" - -val MISSING_SSL_DISABLE_ENTRY = """ -{ - "keys": { - "keyStoreFile": "test.ks.pkcs12", - "keyStorePassword": "changeMe", - "trustStoreFile": "trust.ks.pkcs12", - "trustStorePassword": "changeMeToo" - } -} -""" - -val VALID_SECURITY_WITH_SSL_ENABLED = """ -{ - "sslDisable": false, - "keys": { - "keyStoreFile": "test.ks.pkcs12", - "keyStorePassword": "changeMe", - "trustStoreFile": "trust.ks.pkcs12", - "trustStorePassword": "changeMeToo" - } -} -""" diff --git a/sources/hv-collector-configuration/src/test/resources/sampleConfig.json b/sources/hv-collector-configuration/src/test/resources/sampleConfig.json index 07f0702f..2c3805ef 100644 --- a/sources/hv-collector-configuration/src/test/resources/sampleConfig.json +++ b/sources/hv-collector-configuration/src/test/resources/sampleConfig.json @@ -1,22 +1,13 @@ { "logLevel": "ERROR", - "server": { - "healthCheckApiPort": 5000, - "listenPort": 6000, - "idleTimeoutSec": 1200, - "maxPayloadSizeBytes": 512000 - }, - "cbs": { - "firstRequestDelaySec": 7, - "requestIntervalSec": 900 - }, - "security": { - "sslDisable": false, - "keys": { - "keyStoreFile": "test.ks.pkcs12", - "keyStorePassword": "changeMe", - "trustStoreFile": "trust.ks.pkcs12", - "trustStorePassword": "changeMeToo" - } - } -} + "server.listenPort": 6000, + "server.idleTimeoutSec": 1200, + "server.maxPayloadSizeBytes": 1048576, + "cbs.firstRequestDelaySec": 7, + "cbs.requestIntervalSec": 900, + "security.sslDisable": false, + "security.keys.keyStoreFile": "test.ks.pkcs12", + "security.keys.keyStorePassword": "changeMe", + "security.keys.trustStoreFile": "trust.ks.pkcs12", + "security.keys.trustStorePassword": "changeMeToo" +} \ No newline at end of file diff --git a/sources/hv-collector-main/src/main/docker/base.json b/sources/hv-collector-main/src/main/docker/base.json index e0b9c450..0a5cae07 100644 --- a/sources/hv-collector-main/src/main/docker/base.json +++ b/sources/hv-collector-main/src/main/docker/base.json @@ -1,14 +1,9 @@ { "logLevel": "INFO", - "server": { - "listenPort": 6061, - "idleTimeoutSec": 60, - "maxPayloadSizeBytes": 1048576 - }, - "cbs": { - "firstRequestDelaySec": 10, - "requestIntervalSec": 5 - }, - "security": { - } + "server.listenPort": 6061, + "server.idleTimeoutSec": 60, + "server.maxPayloadSizeBytes": 1048576, + "cbs.firstRequestDelaySec": 10, + "cbs.requestIntervalSec": 5, + "security.sslDisable": true } -- cgit 1.2.3-korg