From 30afcb56b0c6c4529fdaf68d7b061eee44d68d16 Mon Sep 17 00:00:00 2001 From: Jakub Dudycz Date: Wed, 13 Mar 2019 18:44:31 +0100 Subject: Remove environment variables and program arguments - Move all command line program arguments to json file. - Reorganize configuration classes and the way they are passed through application - Implement HV VES configuration stream - Create concrete configuration from partial one - Modify main HV-VES server starting pipeline Change-Id: I6cf874b6904ed768e4820b8132f5f760299c929e Signed-off-by: Jakub Dudycz Issue-ID: DCAEGEN2-1340 --- .../veshv/config/api/ConfigurationModule.kt | 22 ++- .../config/api/model/CollectorConfiguration.kt | 26 --- .../veshv/config/api/model/Configuration.kt | 54 ++++++ .../api/model/ConfigurationProviderParams.kt | 29 ---- .../veshv/config/api/model/Exceptions.kt | 24 +++ .../veshv/config/api/model/KafkaConfiguration.kt | 26 --- .../collectors/veshv/config/api/model/Routing.kt | 77 +++++++++ .../veshv/config/api/model/ServerConfiguration.kt | 42 ----- .../collectors/veshv/config/api/model/routing.kt | 85 --------- .../veshv/config/impl/ArgHvVesConfiguration.kt | 36 ++++ .../veshv/config/impl/ArgVesHvConfiguration.kt | 151 ---------------- .../veshv/config/impl/ConfigurationValidator.kt | 118 +++++++++++++ .../veshv/config/impl/PartialConfiguration.kt | 35 ++-- .../veshv/config/api/ArgVesHvConfigurationTest.kt | 192 --------------------- .../config/api/FileConfigurationReaderTest.kt | 147 ---------------- .../veshv/config/impl/ArgHvVesConfigurationTest.kt | 73 ++++++++ .../config/impl/ConfigurationValidatorTest.kt | 138 +++++++++++++++ .../config/impl/FileConfigurationReaderTest.kt | 153 ++++++++++++++++ .../src/test/resources/sampleConfig.json | 23 +-- 19 files changed, 719 insertions(+), 732 deletions(-) delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/CollectorConfiguration.kt create mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Configuration.kt delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ConfigurationProviderParams.kt create mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Exceptions.kt delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/KafkaConfiguration.kt create mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Routing.kt delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ServerConfiguration.kt delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/routing.kt create mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfiguration.kt delete mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgVesHvConfiguration.kt create mode 100644 sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt delete mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/ArgVesHvConfigurationTest.kt delete mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/FileConfigurationReaderTest.kt create mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfigurationTest.kt create mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt create mode 100644 sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt (limited to 'sources/hv-collector-configuration/src') diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/ConfigurationModule.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/ConfigurationModule.kt index 874cc5b0..5b547a28 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/ConfigurationModule.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/ConfigurationModule.kt @@ -19,13 +19,25 @@ */ package org.onap.dcae.collectors.veshv.config.api -import org.onap.dcae.collectors.veshv.config.api.model.ServerConfiguration -import org.onap.dcae.collectors.veshv.config.impl.ArgVesHvConfiguration +import org.onap.dcae.collectors.veshv.config.api.model.HvVesConfiguration +import org.onap.dcae.collectors.veshv.config.api.model.MissingArgumentException +import org.onap.dcae.collectors.veshv.config.api.model.ValidationException +import org.onap.dcae.collectors.veshv.config.impl.ArgHvVesConfiguration +import org.onap.dcae.collectors.veshv.config.impl.ConfigurationValidator +import org.onap.dcae.collectors.veshv.config.impl.FileConfigurationReader +import org.onap.dcae.collectors.veshv.utils.arrow.throwOnLeft import reactor.core.publisher.Flux class ConfigurationModule { - fun createConfigurationFromCommandLine(args: Array) = - ArgVesHvConfiguration().parse(args) - fun hvVesConfigurationUpdates(): Flux = Flux.never() + private val cmd = ArgHvVesConfiguration() + private val configReader = FileConfigurationReader() + private val configValidator = ConfigurationValidator() + + fun hvVesConfigurationUpdates(args: Array): Flux = + Flux.just(cmd.parse(args)) + .throwOnLeft { MissingArgumentException(it.message, it.cause) } + .map { configReader.loadConfig(it.reader()) } + .map { configValidator.validate(it) } + .throwOnLeft { ValidationException(it.message) } } diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/CollectorConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/CollectorConfiguration.kt deleted file mode 100644 index 7999451e..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/CollectorConfiguration.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018 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.api.model - -/** - * @author Piotr Jaszczyk - * @since May 2018 - */ -data class CollectorConfiguration(val routing: Routing) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Configuration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Configuration.kt new file mode 100644 index 00000000..566f2c08 --- /dev/null +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Configuration.kt @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018 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.api.model + +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityConfiguration +import org.onap.dcae.collectors.veshv.utils.logging.LogLevel +import java.time.Duration + +/** + * @author Piotr Jaszczyk + * @since May 2018 + */ +data class HvVesConfiguration( + val server: ServerConfiguration, + val cbs: CbsConfiguration, + val security: SecurityConfiguration, + val collector: CollectorConfiguration, + val logLevel: LogLevel +) + +data class ServerConfiguration( + val listenPort: Int, + val idleTimeout: Duration, + val maxPayloadSizeBytes: Int +) + +data class CbsConfiguration( + val firstRequestDelay: Duration, + val requestInterval: Duration +) + +data class CollectorConfiguration( + val maxRequestSizeBytes: Int, + val kafkaServers: String, + val routing: Routing, + val dummyMode: Boolean = false +) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ConfigurationProviderParams.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ConfigurationProviderParams.kt deleted file mode 100644 index 847279d9..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ConfigurationProviderParams.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018-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.api.model - -import java.time.Duration - -/** - * @author Jakub Dudycz - * @since July 2018 - */ -data class ConfigurationProviderParams(val firstRequestDelay: Duration, - val requestInterval: Duration) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Exceptions.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Exceptions.kt new file mode 100644 index 00000000..2fc29829 --- /dev/null +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Exceptions.kt @@ -0,0 +1,24 @@ +/* + * ============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.api.model + +class MissingArgumentException(message: String, cause: Throwable?) : RuntimeException(message, cause) + +class ValidationException(message: String) : RuntimeException(message) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/KafkaConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/KafkaConfiguration.kt deleted file mode 100644 index f9dff203..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/KafkaConfiguration.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018 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.api.model - -/** - * @author Piotr Jaszczyk - * @since December 2018 - */ -data class KafkaConfiguration(val bootstrapServers: String, val maximalRequestSizeBytes: Int) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Routing.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Routing.kt new file mode 100644 index 00000000..aab8ecad --- /dev/null +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/Routing.kt @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018-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.api.model + +import arrow.core.Option +import org.onap.dcae.collectors.veshv.domain.RoutedMessage +import org.onap.dcae.collectors.veshv.domain.VesMessage +import org.onap.ves.VesEventOuterClass.CommonEventHeader + +data class Routing(val routes: List) { + + fun routeFor(commonHeader: CommonEventHeader): Option = + Option.fromNullable(routes.find { it.applies(commonHeader) }) +} + +data class Route(val domain: String, val targetTopic: String, val partitioning: (CommonEventHeader) -> Int = { 0 }) { + + fun applies(commonHeader: CommonEventHeader) = commonHeader.domain == domain + + operator fun invoke(message: VesMessage): RoutedMessage = + RoutedMessage(targetTopic, partitioning(message.header), message) +} + + +/* +HvVesConfiguration DSL +*/ + +fun routing(init: RoutingBuilder.() -> Unit): RoutingBuilder = RoutingBuilder().apply(init) + +class RoutingBuilder { + private val routes: MutableList = mutableListOf() + + fun defineRoute(init: RouteBuilder.() -> Unit): RouteBuilder = RouteBuilder() + .apply(init) + .also { routes.add(it) } + + fun build() = Routing(routes.map { it.build() }.toList()) +} + +class RouteBuilder { + + private lateinit var domain: String + private lateinit var targetTopic: String + private lateinit var partitioning: (CommonEventHeader) -> Int + + fun fromDomain(domain: String): RouteBuilder = apply { + this.domain = domain + } + + fun toTopic(targetTopic: String): RouteBuilder = apply { + this.targetTopic = targetTopic + } + + fun withFixedPartitioning(num: Int = 0): RouteBuilder = apply { + partitioning = { num } + } + + fun build() = Route(domain, targetTopic, partitioning) +} diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ServerConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ServerConfiguration.kt deleted file mode 100644 index 8fbc649b..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/ServerConfiguration.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018 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.api.model - -import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityConfiguration -import org.onap.dcae.collectors.veshv.utils.logging.LogLevel -import java.net.InetSocketAddress -import java.time.Duration - -/** - * @author Piotr Jaszczyk - * @since May 2018 - */ -data class ServerConfiguration( - val serverListenAddress: InetSocketAddress, - val kafkaConfiguration: KafkaConfiguration, - val configurationProviderParams: ConfigurationProviderParams, - val securityConfiguration: SecurityConfiguration, - val idleTimeout: Duration, - val healthCheckApiListenAddress: InetSocketAddress, - val maximumPayloadSizeBytes: Int, - val logLevel: LogLevel, - val dummyMode: Boolean = false -) - diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/routing.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/routing.kt deleted file mode 100644 index 847f35ad..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/api/model/routing.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018 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.api.model - -import arrow.core.Option -import org.onap.dcae.collectors.veshv.domain.RoutedMessage -import org.onap.dcae.collectors.veshv.domain.VesMessage -import org.onap.ves.VesEventOuterClass.CommonEventHeader - -data class Routing(val routes: List) { - - fun routeFor(commonHeader: CommonEventHeader): Option = - Option.fromNullable(routes.find { it.applies(commonHeader) }) -} - -data class Route(val domain: String, val targetTopic: String, val partitioning: (CommonEventHeader) -> Int = {0}) { - - fun applies(commonHeader: CommonEventHeader) = commonHeader.domain == domain - - operator fun invoke(message: VesMessage): RoutedMessage = - RoutedMessage(targetTopic, partitioning(message.header), message) -} - - -/* -Configuration DSL - */ - -fun routing(init: RoutingBuilder.() -> Unit): RoutingBuilder { - val conf = RoutingBuilder() - conf.init() - return conf -} - -class RoutingBuilder { - private val routes: MutableList = mutableListOf() - - fun defineRoute(init: RouteBuilder.() -> Unit): RouteBuilder { - val rule = RouteBuilder() - rule.init() - routes.add(rule) - return rule - } - - fun build() = Routing(routes.map { it.build() }.toList()) -} - -class RouteBuilder { - - private lateinit var domain: String - private lateinit var targetTopic: String - private lateinit var partitioning: (CommonEventHeader) -> Int - - fun fromDomain(domain: String) : RouteBuilder = apply { - this.domain = domain - } - - fun toTopic(targetTopic: String) : RouteBuilder = apply { - this.targetTopic = targetTopic - } - - fun withFixedPartitioning(num: Int = 0) : RouteBuilder = apply { - partitioning = { num } - } - - fun build() = Route(domain, targetTopic, partitioning) - -} diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfiguration.kt new file mode 100644 index 00000000..9587d5b0 --- /dev/null +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfiguration.kt @@ -0,0 +1,36 @@ +/* + * ============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 + +import arrow.core.Option +import org.apache.commons.cli.CommandLine +import org.apache.commons.cli.DefaultParser +import org.onap.dcae.collectors.veshv.commandline.ArgBasedConfiguration +import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.CONFIGURATION_FILE +import org.onap.dcae.collectors.veshv.commandline.stringValue +import java.io.File + +internal class ArgHvVesConfiguration : ArgBasedConfiguration(DefaultParser()) { + override val cmdLineOptionsList = listOf(CONFIGURATION_FILE) + + override fun getConfiguration(cmdLine: CommandLine): Option = + cmdLine.stringValue(CONFIGURATION_FILE).map(::File) + +} diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgVesHvConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgVesHvConfiguration.kt deleted file mode 100644 index 08346d30..00000000 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgVesHvConfiguration.kt +++ /dev/null @@ -1,151 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018-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 - -import arrow.core.Option -import arrow.core.fix -import arrow.core.getOrElse -import arrow.instances.option.monad.monad -import arrow.typeclasses.binding -import org.apache.commons.cli.CommandLine -import org.apache.commons.cli.DefaultParser -import org.onap.dcae.collectors.veshv.commandline.ArgBasedConfiguration -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.CONFIGURATION_REQUEST_INTERVAL -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.CONFIGURATION_FIRST_REQUEST_DELAY -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.DUMMY_MODE -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.HEALTH_CHECK_API_PORT -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.IDLE_TIMEOUT_SEC -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.KAFKA_SERVERS -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.KEY_STORE_FILE -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.KEY_STORE_PASSWORD -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.LISTEN_PORT -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.LOG_LEVEL -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.MAXIMUM_PAYLOAD_SIZE_BYTES -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.SSL_DISABLE -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.TRUST_STORE_FILE -import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.TRUST_STORE_PASSWORD -import org.onap.dcae.collectors.veshv.commandline.hasOption -import org.onap.dcae.collectors.veshv.commandline.intValue -import org.onap.dcae.collectors.veshv.commandline.longValue -import org.onap.dcae.collectors.veshv.commandline.stringValue -import org.onap.dcae.collectors.veshv.config.api.model.ConfigurationProviderParams -import org.onap.dcae.collectors.veshv.config.api.model.KafkaConfiguration -import org.onap.dcae.collectors.veshv.config.api.model.ServerConfiguration -import org.onap.dcae.collectors.veshv.domain.WireFrameMessage -import org.onap.dcae.collectors.veshv.ssl.boundary.createSecurityConfiguration -import org.onap.dcae.collectors.veshv.utils.arrow.doOnFailure -import org.onap.dcae.collectors.veshv.utils.logging.LogLevel -import org.onap.dcae.collectors.veshv.utils.logging.Logger -import java.net.InetSocketAddress -import java.time.Duration - - -internal class ArgVesHvConfiguration : ArgBasedConfiguration(DefaultParser()) { - override val cmdLineOptionsList = listOf( - KAFKA_SERVERS, - HEALTH_CHECK_API_PORT, - LISTEN_PORT, - CONFIGURATION_FIRST_REQUEST_DELAY, - CONFIGURATION_REQUEST_INTERVAL, - SSL_DISABLE, - KEY_STORE_FILE, - KEY_STORE_PASSWORD, - TRUST_STORE_FILE, - TRUST_STORE_PASSWORD, - IDLE_TIMEOUT_SEC, - MAXIMUM_PAYLOAD_SIZE_BYTES, - DUMMY_MODE, - LOG_LEVEL - ) - - override fun getConfiguration(cmdLine: CommandLine): Option = - Option.monad().binding { - val healthCheckApiPort = cmdLine.intValue( - HEALTH_CHECK_API_PORT, - DefaultValues.HEALTH_CHECK_API_PORT - ) - val kafkaServers = cmdLine.stringValue(KAFKA_SERVERS).bind() - val listenPort = cmdLine.intValue(LISTEN_PORT).bind() - val idleTimeoutSec = cmdLine.longValue(IDLE_TIMEOUT_SEC, DefaultValues.IDLE_TIMEOUT_SEC) - val maxPayloadSizeBytes = cmdLine.intValue( - MAXIMUM_PAYLOAD_SIZE_BYTES, - DefaultValues.MAX_PAYLOAD_SIZE_BYTES - ) - val dummyMode = cmdLine.hasOption(DUMMY_MODE) - val security = createSecurityConfiguration(cmdLine) - .doOnFailure { ex -> - logger.withError { log("Could not read security keys", ex) } - } - .toOption() - .bind() - val logLevel = cmdLine.stringValue(LOG_LEVEL, DefaultValues.LOG_LEVEL) - val configurationProviderParams = createConfigurationProviderParams(cmdLine).bind() - ServerConfiguration( - serverListenAddress = InetSocketAddress(listenPort), - kafkaConfiguration = KafkaConfiguration(kafkaServers, maxPayloadSizeBytes), - healthCheckApiListenAddress = InetSocketAddress(healthCheckApiPort), - configurationProviderParams = configurationProviderParams, - securityConfiguration = security, - idleTimeout = Duration.ofSeconds(idleTimeoutSec), - maximumPayloadSizeBytes = maxPayloadSizeBytes, - dummyMode = dummyMode, - logLevel = determineLogLevel(logLevel) - ) - }.fix() - - private fun createConfigurationProviderParams(cmdLine: CommandLine): Option = - Option.monad().binding { - val firstRequestDelay = cmdLine.longValue( - CONFIGURATION_FIRST_REQUEST_DELAY, - DefaultValues.CONFIGURATION_FIRST_REQUEST_DELAY - ) - val requestInterval = cmdLine.longValue( - CONFIGURATION_REQUEST_INTERVAL, - DefaultValues.CONFIGURATION_REQUEST_INTERVAL - ) - ConfigurationProviderParams( - Duration.ofSeconds(firstRequestDelay), - Duration.ofSeconds(requestInterval) - ) - }.fix() - - private fun determineLogLevel(logLevel: String) = LogLevel.optionFromString(logLevel) - .getOrElse { - logger.warn { - "Failed to parse $logLevel as $LOG_LEVEL command line. " + - "Using default log level (${DefaultValues.LOG_LEVEL})" - } - LogLevel.valueOf(DefaultValues.LOG_LEVEL) - } - - - internal object DefaultValues { - const val HEALTH_CHECK_API_PORT = 6060 - const val CONFIGURATION_FIRST_REQUEST_DELAY = 10L - const val CONFIGURATION_REQUEST_INTERVAL = 5L - const val IDLE_TIMEOUT_SEC = 60L - const val MAX_PAYLOAD_SIZE_BYTES = WireFrameMessage.DEFAULT_MAX_PAYLOAD_SIZE_BYTES - val LOG_LEVEL = LogLevel.INFO.name - } - - companion object { - private val logger = Logger(ArgVesHvConfiguration::class) - } -} 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 new file mode 100644 index 00000000..6c74c33f --- /dev/null +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt @@ -0,0 +1,118 @@ +/* + * ============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 + +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 +import org.onap.dcae.collectors.veshv.config.api.model.HvVesConfiguration +import org.onap.dcae.collectors.veshv.config.api.model.ServerConfiguration +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityConfiguration +import org.onap.dcae.collectors.veshv.utils.arrow.OptionUtils.binding +import org.onap.dcae.collectors.veshv.utils.arrow.mapBinding +import org.onap.dcae.collectors.veshv.utils.logging.LogLevel +import org.onap.dcae.collectors.veshv.utils.logging.Logger +import java.net.InetSocketAddress +import java.time.Duration + +/** + * @author Jakub Dudycz + * @since March 2019 + */ +internal class ConfigurationValidator { + + fun validate(partialConfig: PartialConfiguration) + : Either = binding { + val logLevel = determineLogLevel(partialConfig.logLevel) + + val serverConfiguration = partialConfig.server.bind() + .let { createServerConfiguration(it).bind() } + + val cbsConfiguration = partialConfig.cbs.bind() + .let { createCbsConfiguration(it).bind() } + + val securityConfiguration = partialConfig.security.bind() + .let { createSecurityConfiguration(it).bind() } + + val collectorConfiguration = partialConfig.collector.bind() + .let { createCollectorConfig(it).bind() } + + HvVesConfiguration( + serverConfiguration, + cbsConfiguration, + securityConfiguration, + collectorConfiguration, + logLevel + ) + }.toEither { ValidationError("Some required configuration options are missing") } + + private fun determineLogLevel(logLevel: Option) = + logLevel.getOrElse { + logger.warn { + "Missing or invalid \"logLevel\" field. " + + "Using default log level ($DEFAULT_LOG_LEVEL)" + } + DEFAULT_LOG_LEVEL + } + + private fun createServerConfiguration(partial: PartialServerConfig) = + partial.mapBinding { + ServerConfiguration( + it.listenPort.bind(), + Duration.ofSeconds(it.idleTimeoutSec.bind().toLong()), + it.maxPayloadSizeBytes.bind() + ) + } + + private fun createCbsConfiguration(partial: PartialCbsConfig) = + partial.mapBinding { + CbsConfiguration( + Duration.ofSeconds(it.firstRequestDelaySec.bind().toLong()), + Duration.ofSeconds(it.requestIntervalSec.bind().toLong()) + ) + } + + private fun createSecurityConfiguration(partial: PartialSecurityConfig) = + partial.keys.map { SecurityConfiguration(Some(it)) } + + private fun createCollectorConfig(partial: PartialCollectorConfig) = + partial.mapBinding { + CollectorConfiguration( + it.maxRequestSizeBytes.bind(), + toKafkaServersString(it.kafkaServers.bind()), + it.routing.bind(), + it.dummyMode.bind() + ) + } + + private fun toKafkaServersString(kafkaServers: List): String = + kafkaServers.joinToString(",") { "${it.hostName}:${it.port}" } + + companion object { + val DEFAULT_LOG_LEVEL = LogLevel.INFO + private val logger = Logger(ConfigurationValidator::class) + } +} + +data class ValidationError(val message: String, val cause: Option = None) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/PartialConfiguration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/PartialConfiguration.kt index 8d9cca73..3e6df3e0 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/PartialConfiguration.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/PartialConfiguration.kt @@ -19,6 +19,7 @@ */ package org.onap.dcae.collectors.veshv.config.impl +import arrow.core.None import arrow.core.Option import org.onap.dcae.collectors.veshv.config.api.model.Routing import org.onap.dcae.collectors.veshv.utils.logging.LogLevel @@ -30,31 +31,29 @@ import java.net.InetSocketAddress * @since February 2019 */ internal data class PartialConfiguration( - val server : Option, - val cbs : Option, - val security : Option, - val kafka : Option, - val logLevel : Option + val server: Option = None, + val cbs: Option = None, + val security: Option = None, + val collector: Option = None, + val logLevel: Option = None ) internal data class PartialServerConfig( - val healthCheckApiPort : Option, - val listenPort : Option, - val idleTimeoutSec : Option, - val maximumPayloadSizeBytes : Option, - val dummyMode : Option + val listenPort: Option = None, + val idleTimeoutSec: Option = None, + val maxPayloadSizeBytes: Option = None ) internal data class PartialCbsConfig( - val firstRequestDelaySec : Option, - val requestIntervalSec : Option + val firstRequestDelaySec: Option = None, + val requestIntervalSec: Option = None ) -internal data class PartialSecurityConfig( - val sslDisable : Option, - val keys : Option) +internal data class PartialSecurityConfig(val keys: Option = None) -internal data class PartialKafkaConfig( - val kafkaServers : Option>, - val routing : Option +internal data class PartialCollectorConfig( + val dummyMode: Option = None, + val maxRequestSizeBytes: Option = None, + val kafkaServers: Option> = None, + val routing: Option = None ) diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/ArgVesHvConfigurationTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/ArgVesHvConfigurationTest.kt deleted file mode 100644 index 0f8d8d0e..00000000 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/ArgVesHvConfigurationTest.kt +++ /dev/null @@ -1,192 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * dcaegen2-collectors-veshv - * ================================================================================ - * Copyright (C) 2018-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.api - -import org.assertj.core.api.Assertions.assertThat -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 -import org.jetbrains.spek.api.dsl.on -import org.onap.dcae.collectors.veshv.commandline.WrongArgumentError -import org.onap.dcae.collectors.veshv.config.api.model.ServerConfiguration -import org.onap.dcae.collectors.veshv.config.impl.ArgVesHvConfiguration -import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingFailure -import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingSuccess -import org.onap.dcae.collectors.veshv.utils.logging.LogLevel -import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys -import java.time.Duration -import kotlin.test.assertNotNull - -/** - * @author Piotr Jaszczyk - * @since May 2018 - */ -object ArgVesHvConfigurationTest : Spek({ - lateinit var cut: ArgVesHvConfiguration - val kafkaBootstrapServers = "dmaap-mr-wro:6666,dmaap-mr-gda:6666" - val healthCheckApiPort = "6070" - val firstRequestDelay = "10" - val requestInterval = "5" - val listenPort = "6969" - val keyStorePassword = "kspass" - val trustStorePassword = "tspass" - val logLevel = LogLevel.DEBUG.name - - beforeEachTest { - cut = ArgVesHvConfiguration() - } - - describe("parsing arguments") { - given("all parameters are present in the long form") { - lateinit var result: ServerConfiguration - - beforeEachTest { - result = cut.parseExpectingSuccess( - "--kafka-bootstrap-servers", kafkaBootstrapServers, - "--health-check-api-port", healthCheckApiPort, - "--listen-port", listenPort, - "--first-request-delay", firstRequestDelay, - "--request-interval", requestInterval, - "--key-store", "/tmp/keys.p12", - "--trust-store", "/tmp/trust.p12", - "--key-store-password", keyStorePassword, - "--trust-store-password", trustStorePassword, - "--log-level", logLevel - ) - } - - it("should set proper kafka bootstrap servers") { - assertThat(result.kafkaConfiguration.bootstrapServers).isEqualTo(kafkaBootstrapServers) - } - - it("should set proper listen port") { - assertThat(result.serverListenAddress.port).isEqualTo(listenPort.toInt()) - } - - - it("should set default listen address") { - assertThat(result.serverListenAddress.address.hostAddress).isEqualTo("0.0.0.0") - } - - it("should set proper health check api port") { - assertThat(result.healthCheckApiListenAddress.port).isEqualTo(healthCheckApiPort.toInt()) - } - - it("should set default health check api address") { - assertThat(result.healthCheckApiListenAddress.address.hostAddress).isEqualTo("0.0.0.0") - } - - it("should set proper first request delay") { - assertThat(result.configurationProviderParams.firstRequestDelay) - .isEqualTo(Duration.ofSeconds(firstRequestDelay.toLong())) - } - - it("should set proper request interval") { - assertThat(result.configurationProviderParams.requestInterval) - .isEqualTo(Duration.ofSeconds(requestInterval.toLong())) - } - - it("should set proper security configuration") { - assertThat(result.securityConfiguration.keys.isEmpty()).isFalse() - - val keys = result.securityConfiguration.keys.orNull() as SecurityKeys - assertNotNull(keys.keyStore()) - assertNotNull(keys.trustStore()) - keys.keyStorePassword().useChecked { - assertThat(it).isEqualTo(keyStorePassword.toCharArray()) - - } - keys.trustStorePassword().useChecked { - assertThat(it).isEqualTo(trustStorePassword.toCharArray()) - } - } - - it("should set proper log level") { - assertThat(result.logLevel).isEqualTo(LogLevel.DEBUG) - } - } - - describe("required parameter is absent") { - on("missing listen port") { - it("should throw exception") { - assertThat( - cut.parseExpectingFailure( - "--ssl-disable", - "--first-request-delay", firstRequestDelay, - "--request-interval", requestInterval - ) - ).isInstanceOf(WrongArgumentError::class.java) - } - } - on("missing configuration url") { - it("should throw exception") { - assertThat( - cut.parseExpectingFailure( - "--listen-port", listenPort, - "--ssl-disable", - "--first-request-delay", firstRequestDelay, - "--request-interval", requestInterval - ) - ).isInstanceOf(WrongArgumentError::class.java) - } - } - } - - describe("correct log level not provided") { - on("missing log level") { - it("should set default INFO value") { - val config = cut.parseExpectingSuccess( - "--kafka-bootstrap-servers", kafkaBootstrapServers, - "--health-check-api-port", healthCheckApiPort, - "--listen-port", listenPort, - "--first-request-delay", firstRequestDelay, - "--request-interval", requestInterval, - "--key-store", "/tmp/keys.p12", - "--trust-store", "/tmp/trust.p12", - "--key-store-password", keyStorePassword, - "--trust-store-password", trustStorePassword - ) - - assertThat(config.logLevel).isEqualTo(LogLevel.INFO) - } - } - - on("incorrect log level") { - it("should set default INFO value") { - val config = cut.parseExpectingSuccess( - "--kafka-bootstrap-servers", kafkaBootstrapServers, - "--health-check-api-port", healthCheckApiPort, - "--listen-port", listenPort, - "--first-request-delay", firstRequestDelay, - "--request-interval", requestInterval, - "--key-store", "/tmp/keys.p12", - "--trust-store", "/tmp/trust.p12", - "--key-store-password", keyStorePassword, - "--trust-store-password", trustStorePassword, - "--log-level", "1" - ) - - assertThat(config.logLevel).isEqualTo(LogLevel.INFO) - } - } - } - } -}) diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/FileConfigurationReaderTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/FileConfigurationReaderTest.kt deleted file mode 100644 index 55da7d02..00000000 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/api/FileConfigurationReaderTest.kt +++ /dev/null @@ -1,147 +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.api - -import arrow.core.Some -import org.jetbrains.spek.api.Spek -import org.assertj.core.api.Assertions.assertThat -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.FileConfigurationReader -import org.onap.dcae.collectors.veshv.config.impl.PartialCbsConfig -import org.onap.dcae.collectors.veshv.config.impl.PartialKafkaConfig -import org.onap.dcae.collectors.veshv.config.impl.PartialSecurityConfig -import org.onap.dcae.collectors.veshv.config.impl.PartialServerConfig -import org.onap.dcae.collectors.veshv.utils.logging.LogLevel -import java.io.InputStreamReader -import java.io.StringReader -import java.net.InetSocketAddress - -/** - * @author Pawel Biniek - * @since February 2019 - */ -internal object FileConfigurationReaderTest : Spek({ - describe("A configuration loader utility") { - - describe("partial configuration loading") { - it("parses enumerations") { - val input = """{"logLevel":"ERROR"}""" - - val config = FileConfigurationReader().loadConfig(StringReader(input)) - assertThat(config.logLevel).isEqualTo(Some(LogLevel.ERROR)) - } - - it("parses simple structure") { - val input = """{ - "server" : { - "healthCheckApiPort" : 12002, - "listenPort" : 12003 - } - } - """.trimIndent() - val config = FileConfigurationReader().loadConfig(StringReader(input)) - assertThat(config.server.nonEmpty()).isTrue() - assertThat(config.server.orNull()?.healthCheckApiPort).isEqualTo(Some(12002)) - assertThat(config.server.orNull()?.listenPort).isEqualTo(Some(12003)) - } - - it("parses ip address") { - val input = """{ "kafka" : { - "kafkaServers": [ - "192.168.255.1:5005", - "192.168.255.26:5006" - ] - } - }""" - - val config = FileConfigurationReader().loadConfig(StringReader(input)) - assertThat(config.kafka.nonEmpty()).isTrue() - val kafka = config.kafka.orNull() as PartialKafkaConfig - assertThat(kafka.kafkaServers.nonEmpty()).isTrue() - val addresses = kafka.kafkaServers.orNull() as Array - assertThat(addresses) - .isEqualTo(arrayOf( - InetSocketAddress("192.168.255.1", 5005), - InetSocketAddress("192.168.255.26", 5006) - )) - } - - it("parses routing array with RoutingAdapter") { - val input = """{ - "kafka" : { - "routing" : [ - { - "fromDomain": "perf3gpp", - "toTopic": "HV_VES_PERF3GPP" - } - ] - } - }""".trimIndent() - val config = FileConfigurationReader().loadConfig(StringReader(input)) - assertThat(config.kafka.nonEmpty()).isTrue() - val kafka = config.kafka.orNull() as PartialKafkaConfig - assertThat(kafka.routing.nonEmpty()).isTrue() - val routing = kafka.routing.orNull() as Routing - routing.run { - assertThat(routes.size).isEqualTo(1) - assertThat(routes[0].domain).isEqualTo("perf3gpp") - assertThat(routes[0].targetTopic).isEqualTo("HV_VES_PERF3GPP") - } - } - } - - describe("complete file loading") { - it("loads actual file") { - val config = FileConfigurationReader().loadConfig( - InputStreamReader( - FileConfigurationReaderTest.javaClass.getResourceAsStream("/sampleConfig.json"))) - assertThat(config).isNotNull - assertThat(config.logLevel).isEqualTo(Some(LogLevel.ERROR)) - - assertThat(config.security.nonEmpty()).isTrue() - val security = config.security.orNull() as PartialSecurityConfig - assertThat(security.sslDisable.orNull()).isFalse() - assertThat(security.keys.nonEmpty()).isTrue() - - assertThat(config.cbs.nonEmpty()).isTrue() - val cbs = config.cbs.orNull() as PartialCbsConfig - assertThat(cbs.firstRequestDelaySec).isEqualTo(Some(7)) - assertThat(cbs.requestIntervalSec).isEqualTo(Some(900)) - - assertThat(config.kafka.nonEmpty()).isTrue() - val kafka = config.kafka.orNull() as PartialKafkaConfig - assertThat(kafka.kafkaServers.nonEmpty()).isTrue() - assertThat(kafka.routing.nonEmpty()).isTrue() - - assertThat(config.server.nonEmpty()).isTrue() - val server = config.server.orNull() as PartialServerConfig - server.run { - assertThat(dummyMode).isEqualTo(Some(false)) - assertThat(healthCheckApiPort).isEqualTo(Some(5000)) - assertThat(idleTimeoutSec).isEqualTo(Some(1200)) - assertThat(listenPort).isEqualTo(Some(6000)) - assertThat(maximumPayloadSizeBytes).isEqualTo(Some(512000)) - } - } - } - } -}) \ No newline at end of file diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfigurationTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfigurationTest.kt new file mode 100644 index 00000000..dbe757c4 --- /dev/null +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ArgHvVesConfigurationTest.kt @@ -0,0 +1,73 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018-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 + +import org.assertj.core.api.Assertions.assertThat +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 +import org.jetbrains.spek.api.dsl.on +import org.onap.dcae.collectors.veshv.commandline.WrongArgumentError +import org.onap.dcae.collectors.veshv.tests.utils.absoluteResourcePath +import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingFailure +import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingSuccess +import java.io.File + +/** + * @author Piotr Jaszczyk + * @since May 2018 + */ +object ArgVesHvConfigurationTest : Spek({ + lateinit var cut: ArgHvVesConfiguration + val configFilePath = javaClass.absoluteResourcePath("sampleConfig.json") + + beforeEachTest { + cut = ArgHvVesConfiguration() + } + + describe("parsing arguments") { + given("all parameters are present in the long form") { + lateinit var result: File + + beforeEachTest { + result = cut.parseExpectingSuccess( + "--configuration-file", configFilePath + ) + } + + it("should read proper configuration file") { + assertThat(result.exists()).isTrue() + } + } + + describe("required parameter is absent") { + on("missing configuration file path") { + it("should throw exception") { + assertThat( + cut.parseExpectingFailure( + "--non-existing-option", "" + ) + ).isInstanceOf(WrongArgumentError::class.java) + } + } + } + } +}) \ No newline at end of file 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 new file mode 100644 index 00000000..12396d23 --- /dev/null +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt @@ -0,0 +1,138 @@ +/* + * ============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 + +import arrow.core.None +import arrow.core.Some +import com.nhaarman.mockitokotlin2.mock +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.fail +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.utils.logging.LogLevel +import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys +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))) + ) + + it("should return ValidationError") { + val result = cut.validate(config) + assertThat(result.isLeft()).isTrue() + } + } + + describe("validating configuration with empty log level") { + val config = PartialConfiguration( + Some(PartialServerConfig( + Some(1), + Some(2), + Some(3) + )), + Some(PartialCbsConfig( + Some(5), + Some(3) + )), + Some(PartialSecurityConfig( + Some(mock()) + )), + Some(PartialCollectorConfig( + Some(true), + Some(4), + Some(emptyList()), + Some(routing { }.build()) + )), + None + ) + + it("should use default log level") { + val result = cut.validate(config) + result.fold( + { + fail("Configuration should have been created successfully") + }, + { + assertThat(it.logLevel).isEqualTo(DEFAULT_LOG_LEVEL) + } + ) + } + } + + describe("validating complete configuration") { + val idleTimeoutSec = 10 + val firstReqDelaySec = 10 + val securityKeys = Some(mock()) + val routing = routing { }.build() + + val config = PartialConfiguration( + Some(PartialServerConfig( + Some(1), + Some(idleTimeoutSec), + Some(2) + )), + Some(PartialCbsConfig( + Some(firstReqDelaySec), + Some(3) + )), + Some(PartialSecurityConfig( + securityKeys + )), + Some(PartialCollectorConfig( + Some(true), + Some(4), + Some(emptyList()), + Some(routing) + )), + Some(LogLevel.INFO) + ) + + it("should create valid configuration") { + val result = cut.validate(config) + result.fold( + { + fail("Configuration should have been created successfully") + }, + { + assertThat(it.server.idleTimeout) + .isEqualTo(Duration.ofSeconds(idleTimeoutSec.toLong())) + + assertThat(it.security.keys) + .isEqualTo(securityKeys) + + assertThat(it.cbs.firstRequestDelay) + .isEqualTo(Duration.ofSeconds(firstReqDelaySec.toLong())) + + assertThat(it.collector.routing) + .isEqualTo(routing) + } + ) + } + } + } +}) 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 new file mode 100644 index 00000000..ab99f13c --- /dev/null +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/FileConfigurationReaderTest.kt @@ -0,0 +1,153 @@ +/* + * ============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 + +import arrow.core.Some +import org.assertj.core.api.Assertions.assertThat +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.tests.utils.resourceAsStream +import org.onap.dcae.collectors.veshv.utils.logging.LogLevel +import java.io.StringReader +import java.net.InetSocketAddress + +/** + * @author Pawel Biniek + * @since February 2019 + */ +internal object FileConfigurationReaderTest : Spek({ + describe("A configuration loader utility") { + val cut = FileConfigurationReader() + + describe("partial configuration loading") { + it("parses enumerations") { + val input = """{"logLevel":"ERROR"}""" + + val config = cut.loadConfig(StringReader(input)) + assertThat(config.logLevel).isEqualTo(Some(LogLevel.ERROR)) + } + + it("parses simple structure") { + val input = """{ + "server" : { + "healthCheckApiPort" : 12002, + "listenPort" : 12003 + } + } + """.trimIndent() + val config = cut.loadConfig(StringReader(input)) + assertThat(config.server.nonEmpty()).isTrue() + assertThat(config.server.orNull()?.listenPort).isEqualTo(Some(12003)) + } + + it("parses ip address") { + val input = """{ "collector" : { + "kafkaServers": [ + "192.168.255.1:5005", + "192.168.255.26:5006" + ] + } + }""" + + val config = cut.loadConfig(StringReader(input)) + assertThat(config.collector.nonEmpty()).isTrue() + val collector = config.collector.orNull() as PartialCollectorConfig + assertThat(collector.kafkaServers.nonEmpty()).isTrue() + val addresses = collector.kafkaServers.orNull() as List + assertThat(addresses) + .isEqualTo(listOf( + InetSocketAddress("192.168.255.1", 5005), + InetSocketAddress("192.168.255.26", 5006) + )) + } + + it("parses routing array with RoutingAdapter") { + val input = """{ + "collector" : { + "routing" : [ + { + "fromDomain": "perf3gpp", + "toTopic": "HV_VES_PERF3GPP" + } + ] + } + }""".trimIndent() + val config = cut.loadConfig(StringReader(input)) + assertThat(config.collector.nonEmpty()).isTrue() + val collector = config.collector.orNull() as PartialCollectorConfig + assertThat(collector.routing.nonEmpty()).isTrue() + val routing = collector.routing.orNull() as Routing + routing.run { + assertThat(routes.size).isEqualTo(1) + assertThat(routes[0].domain).isEqualTo("perf3gpp") + assertThat(routes[0].targetTopic).isEqualTo("HV_VES_PERF3GPP") + } + } + + it("parses invalid log level string to empty option") { + val input = """{ + "logLevel": something + }""".trimMargin() + val config = cut.loadConfig(input.reader()) + + assertThat(config.logLevel.isEmpty()) + } + } + + describe("complete file loading") { + it("loads actual file") { + val config = cut.loadConfig( + javaClass.resourceAsStream("/sampleConfig.json")) + + 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.cbs.nonEmpty()).isTrue() + val cbs = config.cbs.orNull() as PartialCbsConfig + assertThat(cbs.firstRequestDelaySec).isEqualTo(Some(7)) + assertThat(cbs.requestIntervalSec).isEqualTo(Some(900)) + + assertThat(config.collector.nonEmpty()).isTrue() + val collector = config.collector.orNull() as PartialCollectorConfig + collector.run { + assertThat(dummyMode).isEqualTo(Some(false)) + assertThat(maxRequestSizeBytes).isEqualTo(Some(512000)) + assertThat(kafkaServers.nonEmpty()).isTrue() + assertThat(routing.nonEmpty()).isTrue() + } + + assertThat(config.server.nonEmpty()).isTrue() + val server = config.server.orNull() as PartialServerConfig + server.run { + assertThat(idleTimeoutSec).isEqualTo(Some(1200)) + assertThat(listenPort).isEqualTo(Some(6000)) + assertThat(maxPayloadSizeBytes).isEqualTo(Some(512000)) + } + } + } + } +}) + diff --git a/sources/hv-collector-configuration/src/test/resources/sampleConfig.json b/sources/hv-collector-configuration/src/test/resources/sampleConfig.json index b64df05a..b49085e8 100644 --- a/sources/hv-collector-configuration/src/test/resources/sampleConfig.json +++ b/sources/hv-collector-configuration/src/test/resources/sampleConfig.json @@ -1,16 +1,16 @@ { - "server" : { - "healthCheckApiPort" : 5000, - "listenPort" : 6000, - "idleTimeoutSec" : 1200, - "maximumPayloadSizeBytes" : 512000, - "dummyMode" : false + "logLevel": "ERROR", + "server": { + "healthCheckApiPort": 5000, + "listenPort": 6000, + "idleTimeoutSec": 1200, + "maxPayloadSizeBytes": 512000 }, - "cbs" : { + "cbs": { "firstRequestDelaySec": 7, "requestIntervalSec": 900 }, - "security" : { + "security": { "sslDisable": false, "keys": { "keyStoreFile": "test.ks.pkcs12", @@ -19,7 +19,9 @@ "trustStorePassword": "changeMeToo" } }, - "kafka" : { + "collector": { + "dummyMode": false, + "maxRequestSizeBytes": 512000, "kafkaServers": [ "192.168.255.1:5005", "192.168.255.1:5006" @@ -30,6 +32,5 @@ "toTopic": "HV_VES_PERF3GPP" } ] - }, - "logLevel" : "ERROR" + } } \ No newline at end of file -- cgit 1.2.3-korg