aboutsummaryrefslogtreecommitdiffstats
path: root/sources/hv-collector-commandline/src
diff options
context:
space:
mode:
authorJakub Dudycz <jakub.dudycz@nokia.com>2019-02-27 12:23:00 +0100
committerJakub Dudycz <jakub.dudycz@nokia.com>2019-03-05 13:36:57 +0100
commit78be6c808f0a77c6dc39bd5b0bc9af8f4042febd (patch)
treecdc7d1598dd5a3f5ee8f3445872e58f151a122dc /sources/hv-collector-commandline/src
parent7e95f6edd57378ac0cc458d56008f18882acce74 (diff)
Extract module for ArgBasedConfiguration
Change-Id: Ib11700650583378eb347451950a24c5f238382e4 Signed-off-by: Jakub Dudycz <jakub.dudycz@nokia.com> Issue-ID: DCAEGEN2-1292
Diffstat (limited to 'sources/hv-collector-commandline/src')
-rw-r--r--sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/ArgBasedConfiguration.kt57
-rw-r--r--sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOption.kt168
-rw-r--r--sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentError.kt69
-rw-r--r--sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/extensions.kt66
-rw-r--r--sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOptionTest.kt64
-rw-r--r--sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentErrorTest.kt62
6 files changed, 486 insertions, 0 deletions
diff --git a/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/ArgBasedConfiguration.kt b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/ArgBasedConfiguration.kt
new file mode 100644
index 00000000..1e45c923
--- /dev/null
+++ b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/ArgBasedConfiguration.kt
@@ -0,0 +1,57 @@
+/*
+ * ============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.commandline
+
+import arrow.core.Either
+import arrow.core.Option
+import arrow.core.Try
+import arrow.core.flatMap
+import org.apache.commons.cli.CommandLine
+import org.apache.commons.cli.CommandLineParser
+import org.apache.commons.cli.Options
+import java.io.File
+import java.nio.file.Path
+import java.nio.file.Paths
+
+abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
+ abstract val cmdLineOptionsList: List<CommandLineOption>
+
+ fun parse(args: Array<out String>): Either<WrongArgumentError, T> {
+ val parseResult = Try {
+ val commandLineOptions = cmdLineOptionsList.map { it.option }.fold(Options(), Options::addOption)
+ parser.parse(commandLineOptions, args)
+ }
+ return parseResult
+ .toEither()
+ .mapLeft { ex -> WrongArgumentError(ex, cmdLineOptionsList) }
+ .map(this::getConfiguration)
+ .flatMap {
+ it.toEither {
+ WrongArgumentError(
+ message = "Unexpected error when parsing command line arguments",
+ cmdLineOptionsList = cmdLineOptionsList)
+ }
+ }
+ }
+
+ protected abstract fun getConfiguration(cmdLine: CommandLine): Option<T>
+
+ protected fun stringPathToPath(path: String): Path = Paths.get(File(path).toURI())
+}
diff --git a/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOption.kt b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOption.kt
new file mode 100644
index 00000000..0c3f60bb
--- /dev/null
+++ b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOption.kt
@@ -0,0 +1,168 @@
+/*
+ * ============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.commandline
+
+import org.apache.commons.cli.Option
+
+
+enum class CommandLineOption(val option: Option, val required: Boolean = false) {
+ HEALTH_CHECK_API_PORT(
+ Option.builder("H")
+ .longOpt("health-check-api-port")
+ .hasArg()
+ .desc("Health check rest api listen port")
+ .build()
+ ),
+ LISTEN_PORT(
+ Option.builder("p")
+ .longOpt("listen-port")
+ .hasArg()
+ .desc("Listen port")
+ .build(),
+ required = true
+ ),
+ CONSUL_CONFIG_URL(
+ Option.builder("c")
+ .longOpt("config-url")
+ .hasArg()
+ .desc("URL of ves configuration on consul")
+ .build(),
+ required = true
+ ),
+ CONSUL_FIRST_REQUEST_DELAY(
+ Option.builder("d")
+ .longOpt("first-request-delay")
+ .hasArg()
+ .desc("Delay of first request to consul in seconds")
+ .build()
+ ),
+ CONSUL_REQUEST_INTERVAL(
+ Option.builder("I")
+ .longOpt("request-interval")
+ .hasArg()
+ .desc("Interval of consul configuration requests in seconds")
+ .build()
+ ),
+ VES_HV_PORT(
+ Option.builder("v")
+ .longOpt("ves-port")
+ .hasArg()
+ .desc("VesHvCollector port")
+ .build(),
+ required = true
+ ),
+ VES_HV_HOST(
+ Option.builder("h")
+ .longOpt("ves-host")
+ .hasArg()
+ .desc("VesHvCollector host")
+ .build(),
+ required = true
+ ),
+ KAFKA_SERVERS(
+ Option.builder("s")
+ .longOpt("kafka-bootstrap-servers")
+ .hasArg()
+ .desc("Comma-separated Kafka bootstrap servers in <host>:<port> format")
+ .build(),
+ required = true
+ ),
+ KAFKA_TOPICS(
+ Option.builder("f")
+ .longOpt("kafka-topics")
+ .hasArg()
+ .desc("Comma-separated Kafka topics")
+ .build(),
+ required = true
+ ),
+ SSL_DISABLE(
+ Option.builder("l")
+ .longOpt("ssl-disable")
+ .desc("Disable SSL encryption")
+ .build()
+ ),
+ KEY_STORE_FILE(
+ Option.builder("k")
+ .longOpt("key-store")
+ .hasArg()
+ .desc("Key store in PKCS12 format")
+ .build()
+ ),
+ KEY_STORE_PASSWORD(
+ Option.builder("kp")
+ .longOpt("key-store-password")
+ .hasArg()
+ .desc("Key store password")
+ .build()
+ ),
+ TRUST_STORE_FILE(
+ Option.builder("t")
+ .longOpt("trust-store")
+ .hasArg()
+ .desc("File with trusted certificate bundle in PKCS12 format")
+ .build()
+ ),
+ TRUST_STORE_PASSWORD(
+ Option.builder("tp")
+ .longOpt("trust-store-password")
+ .hasArg()
+ .desc("Trust store password")
+ .build()
+ ),
+ IDLE_TIMEOUT_SEC(
+ Option.builder("i")
+ .longOpt("idle-timeout-sec")
+ .hasArg()
+ .desc(
+ """Idle timeout for remote hosts. After given time without any data exchange the
+ |connection might be closed.""".trimMargin()
+ )
+ .build()
+ ),
+ MAXIMUM_PAYLOAD_SIZE_BYTES(
+ Option.builder("m")
+ .longOpt("max-payload-size")
+ .hasArg()
+ .desc("Maximum supported payload size in bytes")
+ .build()
+ ),
+ LOG_LEVEL(
+ Option.builder("ll")
+ .longOpt("log-level")
+ .hasArg()
+ .desc("Log level")
+ .build()
+ ),
+ DUMMY_MODE(
+ Option.builder("u")
+ .longOpt("dummy")
+ .desc("If present will start in dummy mode (dummy external services)")
+ .build()
+ );
+
+ fun environmentVariableName(prefix: String = DEFAULT_ENV_PREFIX): String =
+ option.longOpt.toUpperCase().replace('-', '_').let { mainPart ->
+ "${prefix}_${mainPart}"
+ }
+
+ companion object {
+ private const val DEFAULT_ENV_PREFIX = "VESHV"
+ }
+}
diff --git a/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentError.kt b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentError.kt
new file mode 100644
index 00000000..f3749b35
--- /dev/null
+++ b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentError.kt
@@ -0,0 +1,69 @@
+/*
+ * ============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.commandline
+
+import arrow.core.Option
+import org.apache.commons.cli.HelpFormatter
+import org.apache.commons.cli.Options
+
+
+data class WrongArgumentError(
+ val message: String,
+ val cause: Throwable? = null,
+ val cmdLineOptionsList: List<CommandLineOption>) {
+
+ constructor(par: Throwable, cmdLineOptionsList: List<CommandLineOption>) :
+ this(par.message ?: "",
+ par,
+ cmdLineOptionsList)
+
+ fun printMessage() {
+ println(message)
+ }
+
+ fun printHelp(programName: String) {
+ val formatter = HelpFormatter()
+ val footer = "All parameters can be specified as environment variables using upper-snake-case full " +
+ "name with prefix `VESHV_`."
+
+ formatter.printHelp(
+ programName,
+ generateRequiredParametersNote(cmdLineOptionsList),
+ getOptions(),
+ footer)
+ }
+
+ private fun getOptions() = cmdLineOptionsList.map { it.option }.fold(Options(), Options::addOption)
+
+ companion object {
+ fun generateRequiredParametersNote(cmdLineOptionsList: List<CommandLineOption>): String {
+ val requiredParams = Option.fromNullable(cmdLineOptionsList.filter { it.required }
+ .takeUnless { it.isEmpty() })
+ return requiredParams.fold(
+ { "" },
+ {
+ it.map { commandLineOption -> commandLineOption.option.opt }
+ .joinToString(prefix = "Required parameters: ", separator = ", ")
+ }
+ )
+ }
+ }
+
+}
diff --git a/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/extensions.kt b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/extensions.kt
new file mode 100644
index 00000000..c0fbcde6
--- /dev/null
+++ b/sources/hv-collector-commandline/src/main/kotlin/org/onap/dcae/collectors/veshv/commandline/extensions.kt
@@ -0,0 +1,66 @@
+/*
+ * ============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.commandline
+
+import arrow.core.Option
+import arrow.core.getOrElse
+import arrow.effects.IO
+import arrow.syntax.function.curried
+import org.apache.commons.cli.CommandLine
+import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure
+import org.onap.dcae.collectors.veshv.utils.arrow.fromNullablesChain
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since June 2018
+ */
+
+fun handleWrongArgumentError(programName: String, err: WrongArgumentError): IO<Unit> = IO {
+ err.printMessage()
+ err.printHelp(programName)
+}.flatMap { ExitFailure(2).io() }
+
+val handleWrongArgumentErrorCurried = ::handleWrongArgumentError.curried()
+
+fun CommandLine.longValue(cmdLineOpt: CommandLineOption, default: Long): Long =
+ longValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.stringValue(cmdLineOpt: CommandLineOption, default: String): String =
+ optionValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.intValue(cmdLineOpt: CommandLineOption, default: Int): Int =
+ intValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
+ optionValue(cmdLineOpt).map(String::toInt)
+
+fun CommandLine.longValue(cmdLineOpt: CommandLineOption): Option<Long> =
+ optionValue(cmdLineOpt).map(String::toLong)
+
+fun CommandLine.stringValue(cmdLineOpt: CommandLineOption): Option<String> =
+ optionValue(cmdLineOpt)
+
+fun CommandLine.hasOption(cmdLineOpt: CommandLineOption): Boolean =
+ this.hasOption(cmdLineOpt.option.opt) ||
+ System.getenv(cmdLineOpt.environmentVariableName()) != null
+
+private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption) = Option.fromNullablesChain(
+ getOptionValue(cmdLineOpt.option.opt),
+ { System.getenv(cmdLineOpt.environmentVariableName()) })
diff --git a/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOptionTest.kt b/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOptionTest.kt
new file mode 100644
index 00000000..736710ff
--- /dev/null
+++ b/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/CommandLineOptionTest.kt
@@ -0,0 +1,64 @@
+/*
+ * ============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.commandline
+
+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.CommandLineOption.DUMMY_MODE
+import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.KAFKA_SERVERS
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+class CommandLineOptionTest : Spek({
+ describe("command line options enum") {
+ describe("environment variables") {
+ given("sample option and prefix") {
+ val opt = KAFKA_SERVERS
+ val prefix = "CONFIG"
+
+ on("calling environmentVariableName") {
+ val result = opt.environmentVariableName(prefix)
+
+ it("should return prefixed upper snake cased long option name") {
+ assertThat(result).isEqualTo("CONFIG_KAFKA_BOOTSTRAP_SERVERS")
+ }
+ }
+ }
+
+ given("sample option without prefix") {
+ val opt = DUMMY_MODE
+
+ on("calling environmentVariableName") {
+ val result = opt.environmentVariableName()
+
+ it("should return prefixed upper snake cased long option name") {
+ assertThat(result).isEqualTo("VESHV_DUMMY")
+ }
+ }
+ }
+ }
+ }
+})
diff --git a/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentErrorTest.kt b/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentErrorTest.kt
new file mode 100644
index 00000000..e177294f
--- /dev/null
+++ b/sources/hv-collector-commandline/src/test/kotlin/org/onap/dcae/collectors/veshv/commandline/WrongArgumentErrorTest.kt
@@ -0,0 +1,62 @@
+/*
+ * ============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.commandline
+
+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.CommandLineOption.HEALTH_CHECK_API_PORT
+import org.onap.dcae.collectors.veshv.commandline.CommandLineOption.LISTEN_PORT
+
+
+class WrongArgumentErrorTest : Spek({
+
+ describe("help message logic test") {
+
+ given("at least one required option") {
+ val filledOptionList = listOf(
+ HEALTH_CHECK_API_PORT,
+ LISTEN_PORT)
+ on("help message preparation") {
+ val requiredParameters = WrongArgumentError.generateRequiredParametersNote(filledOptionList)
+
+ it("should print out required fields") {
+ assertThat(requiredParameters).isEqualTo("Required parameters: p")
+ }
+ }
+ }
+
+ given("no required option") {
+ val filledOptionList = listOf(HEALTH_CHECK_API_PORT)
+
+ on("help message preparation") {
+ val requiredParameters = WrongArgumentError.generateRequiredParametersNote(filledOptionList)
+
+ it("should not print required fields") {
+ assertThat(requiredParameters).isEqualTo("")
+ }
+ }
+ }
+ }
+
+})