Rework argument configuration 59/58859/1
authorJakub Dudycz <jakub.dudycz@nokia.com>
Tue, 24 Jul 2018 09:48:12 +0000 (11:48 +0200)
committerPiotr Jaszczyk <piotr.jaszczyk@nokia.com>
Fri, 3 Aug 2018 07:41:09 +0000 (09:41 +0200)
- Unify names of argument configuration classes in
  DCAE APP simulator, XNF simualtor and VES HV Collector
- Make some of the arguments required
- Adjust docker-compose and Dockerfiles
- Adjust test cases and error handling

Closes ONAP-683

Change-Id: I4a9d43791cced9dcb52eb83e2f7956462e8712d9
Signed-off-by: Jakub Dudycz <jakub.dudycz@nokia.com>
Issue-ID: DCAEGEN2-601

18 files changed:
docker-compose.yml
hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt
hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/model/ServerConfiguration.kt
hv-collector-dcae-app-simulator/Dockerfile
hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgDcaeAppSimConfiguration.kt [moved from hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfiguration.kt with 57% similarity]
hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/main.kt
hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgDcaeAppSimulatorConfigurationTest.kt [moved from hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfigurationTest.kt with 72% similarity]
hv-collector-main/Dockerfile
hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt [moved from hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt with 74% similarity]
hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt
hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt [moved from hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt with 75% similarity]
hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentError.kt
hv-collector-xnf-simulator/Dockerfile
hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgXnfSimulatorConfiguration.kt [moved from hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt with 74% similarity]
hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt
hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgXnfSimulatorConfiurationTest.kt [moved from hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt with 63% similarity]

index 6c4bf73..f0713c7 100644 (file)
@@ -35,6 +35,7 @@ services:
 #      dockerfile: Dockerfile
     ports:
       - "6061:6061/tcp"
+    command: ["--listen-port", "6061","--config-url", "http://consul:8500/v1/kv/veshv-config"]
     depends_on:
       - kafka
       - consul
@@ -47,7 +48,8 @@ services:
 #      context: hv-collector-xnf-simulator
 #      dockerfile: Dockerfile
     ports:
-      - "8000:5000/tcp"
+      - "6062:6062/tcp"
+    command: ["--listen-port", "6062", "--ves-host", "ves-hv-collector", "--ves-port", "6061"]
     depends_on:
       - ves-hv-collector
     volumes:
@@ -59,6 +61,7 @@ services:
 #      context: hv-collector-dcae-app-simulator
 #      dockerfile: Dockerfile
     ports:
-      - "8100:5000/tcp"
+      - "6063:6063/tcp"
+    command: ["--listen-port", "6063", "--kafka-bootstrap-servers", "kafka:9092", "--kafka-topics", "ves_hvRanMeas"]
     depends_on:
       - kafka
index 61e1ebf..c28b151 100644 (file)
@@ -58,7 +58,7 @@ internal class NettyTcpServer(private val serverConfig: ServerConfiguration,
     private fun configureServer(opts: ServerOptions.Builder<*>) {
         val sslContext: Option<SslContext> = sslContextFactory.createSslContext(serverConfig.securityConfiguration)
         if (sslContext.isDefined()) opts.sslContext(sslContext.orNull())
-        opts.port(serverConfig.port)
+        opts.port(serverConfig.listenPort)
     }
 
     private fun handleConnection(nettyInbound: NettyInbound): Mono<Void> {
index 93ad719..b0f3ec0 100644 (file)
@@ -27,7 +27,7 @@ import java.time.Duration
  * @since May 2018
  */
 data class ServerConfiguration(
-        val port: Int,
+        val listenPort: Int,
         val configurationProviderParams: ConfigurationProviderParams,
         val securityConfiguration: SecurityConfiguration,
         val idleTimeout: Duration,
index 68b562d..39bd878 100644 (file)
@@ -5,11 +5,8 @@ LABEL license.name="The Apache Software License, Version 2.0"
 LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
 LABEL maintainer="Nokia Wroclaw ONAP Team"
 
-EXPOSE 5000
-
 WORKDIR /opt/ves-hv-dcae-app-simulator
 ENTRYPOINT ["java", "-cp", "*:", "org.onap.dcae.collectors.veshv.simulators.dcaeapp.MainKt"]
-CMD ["--kafka-bootstrap-servers", "kafka:9092", "--kafka-topics", "ves_hvRanMeas", "--listen-port", "5000"]
 COPY target/libs/external/* ./
 COPY target/libs/internal/* ./
 COPY target/hv-collector-dcae-app-simulator-*.jar ./
 */
 package org.onap.dcae.collectors.veshv.simulators.dcaeapp.config
 
+import arrow.core.ForOption
+import arrow.core.Option
+import arrow.core.fix
+import arrow.instances.extensions
+import arrow.typeclasses.binding
 import org.apache.commons.cli.CommandLine
 import org.apache.commons.cli.DefaultParser
-import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.DefaultValues.API_PORT
 import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KAFKA_SERVERS
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KAFKA_TOPICS
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.LISTEN_PORT
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.*
 
-internal object DefaultValues {
-    const val API_PORT = 8080
-    const val KAFKA_SERVERS = "kafka:9092"
-    const val KAFKA_TOPICS = "ves_hvRanMeas"
-}
-
-class ArgBasedDcaeAppSimConfiguration : ArgBasedConfiguration<DcaeAppSimConfiguration>(DefaultParser()) {
+class ArgDcaeAppSimConfiguration : ArgBasedConfiguration<DcaeAppSimConfiguration>(DefaultParser()) {
     override val cmdLineOptionsList: List<CommandLineOption> = listOf(
             LISTEN_PORT,
             KAFKA_SERVERS,
             KAFKA_TOPICS
     )
 
-    override fun getConfiguration(cmdLine: CommandLine): DcaeAppSimConfiguration {
-        val port = cmdLine.intValue(LISTEN_PORT, API_PORT)
-        val kafkaBootstrapServers = cmdLine.stringValue(KAFKA_SERVERS, DefaultValues.KAFKA_SERVERS)
-        val kafkaTopics = cmdLine.stringValue(KAFKA_TOPICS, DefaultValues.KAFKA_TOPICS).split(",").toSet()
-        return DcaeAppSimConfiguration(
-                port,
-                kafkaBootstrapServers,
-                kafkaTopics)
-    }
+    override fun getConfiguration(cmdLine: CommandLine): Option<DcaeAppSimConfiguration> =
+            ForOption extensions {
+                binding {
+                    val listenPort = cmdLine
+                            .intValue(LISTEN_PORT)
+                            .bind()
+                    val kafkaBootstrapServers = cmdLine
+                            .stringValue(KAFKA_SERVERS)
+                            .bind()
+                    val kafkaTopics = cmdLine
+                            .stringValue(KAFKA_TOPICS)
+                            .map { it.split(",").toSet() }
+                            .bind()
 
+                    DcaeAppSimConfiguration(
+                            listenPort,
+                            kafkaBootstrapServers,
+                            kafkaTopics)
+                }.fix()
+            }
 }
index fb28bc2..9f84fc4 100644 (file)
@@ -20,7 +20,7 @@
 package org.onap.dcae.collectors.veshv.simulators.dcaeapp
 
 import arrow.effects.IO
-import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.ArgBasedDcaeAppSimConfiguration
+import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.ArgDcaeAppSimConfiguration
 import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.DcaeAppSimConfiguration
 import org.onap.dcae.collectors.veshv.simulators.dcaeapp.kafka.ConsumerFactory
 import org.onap.dcae.collectors.veshv.simulators.dcaeapp.remote.ApiServer
@@ -35,7 +35,7 @@ private val logger = Logger(PACKAGE_NAME)
 const val PROGRAM_NAME = "java $PACKAGE_NAME.MainKt"
 
 fun main(args: Array<String>) =
-        ArgBasedDcaeAppSimConfiguration().parse(args)
+        ArgDcaeAppSimConfiguration().parse(args)
                 .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME))
                 .map(::startApp)
                 .unsafeRunEitherSync(
@@ -28,14 +28,15 @@ import org.jetbrains.spek.api.dsl.it
 import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError
 
 
-internal class ArgBasedDcaeAppSimConfigurationTest : Spek({
+internal class ArgDcaeAppSimulatorConfigurationTest : Spek({
 
-    lateinit var cut: ArgBasedDcaeAppSimConfiguration
+    lateinit var cut: ArgDcaeAppSimConfiguration
+    val listenPort = "1234"
     val kafkaBootstrapServers = "localhosting:123,localhostinger:12345"
     val kafkaTopics = "top1,top2"
 
     beforeEachTest {
-        cut = ArgBasedDcaeAppSimConfiguration()
+        cut = ArgDcaeAppSimConfiguration()
     }
 
     fun parseExpectingSuccess(vararg cmdLine: String): DcaeAppSimConfiguration =
@@ -56,14 +57,15 @@ internal class ArgBasedDcaeAppSimConfigurationTest : Spek({
         given("all parameters are present in the long form") {
 
             beforeEachTest {
-                result = parseExpectingSuccess("--listen-port", "6969",
+                result = parseExpectingSuccess(
+                        "--listen-port", listenPort,
                         "--kafka-bootstrap-servers", kafkaBootstrapServers,
                         "--kafka-topics", kafkaTopics
                 )
             }
 
             it("should set proper port") {
-                assertThat(result.apiPort).isEqualTo(6969)
+                assertThat(result.apiPort).isEqualTo(listenPort.toInt())
             }
 
 
@@ -81,13 +83,14 @@ internal class ArgBasedDcaeAppSimConfigurationTest : Spek({
         given("some parameters are present in the short form") {
 
             beforeEachTest {
-                result = parseExpectingSuccess("-p", "666",
+                result = parseExpectingSuccess(
+                        "-p", listenPort,
                         "--kafka-bootstrap-servers", kafkaBootstrapServers,
                         "-f", kafkaTopics)
             }
 
             it("should set proper port") {
-                assertThat(result.apiPort).isEqualTo(666)
+                assertThat(result.apiPort).isEqualTo(listenPort.toInt())
             }
 
             it("should set proper kafka bootstrap servers") {
@@ -101,29 +104,31 @@ internal class ArgBasedDcaeAppSimConfigurationTest : Spek({
             }
         }
 
-        given("all optional parameters are absent") {
-
-            beforeEachTest {
-                result = parseExpectingSuccess("-s", kafkaBootstrapServers, "-f", kafkaTopics)
-            }
-
-            it("should set default port") {
-                assertThat(result.apiPort).isEqualTo(DefaultValues.API_PORT)
-            }
-        }
-
         describe("required parameter is absent") {
             given("kafka topics are missing") {
                 it("should throw exception") {
-                    assertThat(parseExpectingFailure("-s", kafkaBootstrapServers))
-                            .isInstanceOf(WrongArgumentError::class.java)
+                    assertThat(parseExpectingFailure(
+                            "-p", listenPort,
+                            "-s", kafkaBootstrapServers
+                    )).isInstanceOf(WrongArgumentError::class.java)
+                }
+            }
+
+            given("kafka bootstrap servers is missing") {
+                it("should throw exception") {
+                    assertThat(parseExpectingFailure(
+                            "-p", listenPort,
+                            "-f", kafkaTopics
+                    )).isInstanceOf(WrongArgumentError::class.java)
                 }
             }
 
-            given("kafka bootstrap servers are missing") {
+            given("listen port is missing") {
                 it("should throw exception") {
-                    assertThat(parseExpectingFailure("-f", kafkaTopics))
-                            .isInstanceOf(WrongArgumentError::class.java)
+                    assertThat(parseExpectingFailure(
+                            "-p", kafkaTopics,
+                            "-s", kafkaBootstrapServers
+                    )).isInstanceOf(WrongArgumentError::class.java)
                 }
             }
         }
index cab61dc..c077440 100644 (file)
@@ -5,11 +5,8 @@ LABEL license.name="The Apache Software License, Version 2.0"
 LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
 LABEL maintainer="Nokia Wroclaw ONAP Team"
 
-EXPOSE 6061
-
 WORKDIR /opt/ves-hv-collector
 ENTRYPOINT ["java", "-cp", "*:", "org.onap.dcae.collectors.veshv.main.MainKt"]
-CMD ["--listen-port", "6061","--config-url", "http://consul:8500/v1/kv/veshv-config"]
 COPY target/libs/external/* ./
 COPY target/libs/internal/* ./
 COPY target/hv-collector-main-*.jar ./
  */
 package org.onap.dcae.collectors.veshv.main
 
+import arrow.core.ForOption
+import arrow.core.Option
+import arrow.core.fix
+import arrow.instances.extensions
+import arrow.typeclasses.binding
 import org.apache.commons.cli.CommandLine
 import org.apache.commons.cli.DefaultParser
 import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
@@ -28,7 +33,7 @@ import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.*
 import java.time.Duration
 
-internal class ArgBasedServerConfiguration : ArgBasedConfiguration<ServerConfiguration>(DefaultParser()) {
+internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration>(DefaultParser()) {
     override val cmdLineOptionsList = listOf(
             LISTEN_PORT,
             CONSUL_CONFIG_URL,
@@ -42,19 +47,24 @@ internal class ArgBasedServerConfiguration : ArgBasedConfiguration<ServerConfigu
             DUMMY_MODE
     )
 
-    override fun getConfiguration(cmdLine: CommandLine): ServerConfiguration {
-        val port = cmdLine.intValue(LISTEN_PORT, DefaultValues.PORT)
-        val idleTimeoutSec = cmdLine.longValue(IDLE_TIMEOUT_SEC, DefaultValues.IDLE_TIMEOUT_SEC)
-        val dummyMode = cmdLine.hasOption(DUMMY_MODE)
-        val security = createSecurityConfiguration(cmdLine)
-        val configurationProviderParams = createConfigurationProviderParams(cmdLine);
-        return ServerConfiguration(
-                port = port,
-                configurationProviderParams = configurationProviderParams,
-                securityConfiguration = security,
-                idleTimeout = Duration.ofSeconds(idleTimeoutSec),
-                dummyMode = dummyMode)
-    }
+    override fun getConfiguration(cmdLine: CommandLine): Option<ServerConfiguration> =
+            ForOption extensions {
+                binding {
+                    val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
+                    val idleTimeoutSec = cmdLine.longValue(IDLE_TIMEOUT_SEC, DefaultValues.IDLE_TIMEOUT_SEC)
+                    val dummyMode = cmdLine.hasOption(DUMMY_MODE)
+                    val security = createSecurityConfiguration(cmdLine)
+                    val configurationProviderParams = createConfigurationProviderParams(cmdLine)
+
+                    ServerConfiguration(
+                            listenPort = listenPort,
+                            configurationProviderParams = configurationProviderParams,
+                            securityConfiguration = security,
+                            idleTimeout = Duration.ofSeconds(idleTimeoutSec),
+                            dummyMode = dummyMode)
+                }.fix()
+            }
+
 
     private fun createConfigurationProviderParams(cmdLine: CommandLine): ConfigurationProviderParams {
         val configUrl = cmdLine.stringValue(CONSUL_CONFIG_URL, DefaultValues.CONFIG_URL)
@@ -83,7 +93,6 @@ internal class ArgBasedServerConfiguration : ArgBasedConfiguration<ServerConfigu
     }
 
     internal object DefaultValues {
-        const val PORT = 6061
         const val CONSUL_FIRST_REQUEST_DELAY = 10L
         const val CONSUL_REQUEST_INTERVAL = 5L
         const val CONFIG_URL = ""
index aa1f67b..44d09d4 100644 (file)
@@ -34,7 +34,7 @@ private val logger = Logger("org.onap.dcae.collectors.veshv.main")
 private const val PROGRAM_NAME = "java org.onap.dcae.collectors.veshv.main.MainKt"
 
 fun main(args: Array<String>) =
-        ArgBasedServerConfiguration().parse(args)
+        ArgVesHvConfiguration().parse(args)
                 .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME))
                 .map(::createServer)
                 .map {
@@ -27,8 +27,9 @@ 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.domain.SecurityConfiguration
-import org.onap.dcae.collectors.veshv.main.ArgBasedServerConfiguration.*
+import org.onap.dcae.collectors.veshv.main.ArgVesHvConfiguration.DefaultValues
 import org.onap.dcae.collectors.veshv.model.ServerConfiguration
+import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError
 import java.nio.file.Paths
 import java.time.Duration
 
@@ -36,8 +37,8 @@ import java.time.Duration
  * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
  * @since May 2018
  */
-object ArgBasedServerConfigurationTest : Spek({
-    lateinit var cut: ArgBasedServerConfiguration
+object ArgVesHvConfigurationTest : Spek({
+    lateinit var cut: ArgVesHvConfiguration
     val configurationUrl = "http://test-address/test"
     val firstRequestDelay = "10"
     val requestInterval = "5"
@@ -47,15 +48,20 @@ object ArgBasedServerConfigurationTest : Spek({
     val trustCert = Paths.get("/", "etc", "ves", "trusted.crt")
 
     beforeEachTest {
-        cut = ArgBasedServerConfiguration()
+        cut = ArgVesHvConfiguration()
     }
 
     fun parse(vararg cmdLine: String): ServerConfiguration =
             cut.parse(cmdLine).fold(
-                    {throw AssertionError("Parsing result should be present")},
+                    { throw AssertionError("Parsing result should be present") },
                     ::identity
             )
 
+    fun parseExpectingFailure(vararg cmdLine: String) =
+            cut.parse(cmdLine).fold(::identity) {
+                throw AssertionError("parsing should have failed")
+            }
+
     describe("parsing arguments") {
         given("all parameters are present in the long form") {
             lateinit var result: ServerConfiguration
@@ -72,17 +78,17 @@ object ArgBasedServerConfigurationTest : Spek({
             }
 
             it("should set proper port") {
-                assertThat(result.port).isEqualTo(6969)
+                assertThat(result.listenPort).isEqualTo(listenPort.toInt())
             }
 
             it("should set proper first consul request delay") {
                 assertThat(result.configurationProviderParams.firstRequestDelay)
-                        .isEqualTo(Duration.ofSeconds(10))
+                        .isEqualTo(Duration.ofSeconds(firstRequestDelay.toLong()))
             }
 
             it("should set proper consul request interval") {
                 assertThat(result.configurationProviderParams.requestInterval)
-                        .isEqualTo(Duration.ofSeconds(5))
+                        .isEqualTo(Duration.ofSeconds(requestInterval.toLong()))
             }
 
             it("should set proper config url") {
@@ -101,16 +107,16 @@ object ArgBasedServerConfigurationTest : Spek({
             lateinit var result: ServerConfiguration
 
             beforeEachTest {
-                result = parse("-p", "666", "-c", configurationUrl, "-d", firstRequestDelay)
+                result = parse("-p", listenPort, "-c", configurationUrl, "-d", firstRequestDelay)
             }
 
             it("should set proper port") {
-                assertThat(result.port).isEqualTo(666)
+                assertThat(result.listenPort).isEqualTo(listenPort.toInt())
             }
 
             it("should set proper first consul request delay") {
                 assertThat(result.configurationProviderParams.firstRequestDelay)
-                        .isEqualTo(Duration.ofSeconds(10))
+                        .isEqualTo(Duration.ofSeconds(firstRequestDelay.toLong()))
             }
 
             it("should set proper config url") {
@@ -123,11 +129,7 @@ object ArgBasedServerConfigurationTest : Spek({
             lateinit var result: ServerConfiguration
 
             beforeEachTest {
-                result = parse()
-            }
-
-            it("should set default port") {
-                assertThat(result.port).isEqualTo(DefaultValues.PORT)
+                result = parse("--listen-port", listenPort)
             }
 
             it("should set default config url") {
@@ -161,5 +163,21 @@ object ArgBasedServerConfigurationTest : Spek({
                 }
             }
         }
+
+        describe("required parameter is absent") {
+            given("listen port is missing") {
+                it("should throw exception") {
+                    assertThat(parseExpectingFailure(
+                            "--ssl-disable",
+                            "--config-url", configurationUrl,
+                            "--first-request-delay", firstRequestDelay,
+                            "--request-interval", requestInterval,
+                            "--private-key-file", pk.toFile().absolutePath,
+                            "--cert-file", cert.toFile().absolutePath,
+                            "--trust-cert-file", trustCert.toFile().absolutePath)
+                    ).isInstanceOf(WrongArgumentError::class.java)
+                }
+            }
+        }
     }
 })
index 4921953..9c873a0 100644 (file)
@@ -22,6 +22,7 @@ package org.onap.dcae.collectors.veshv.utils.commandline
 import arrow.core.Either
 import arrow.core.Option
 import arrow.core.Try
+import arrow.core.flatMap
 import arrow.core.getOrElse
 import org.apache.commons.cli.CommandLine
 import org.apache.commons.cli.CommandLineParser
@@ -42,9 +43,16 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
                 .toEither()
                 .mapLeft { ex -> WrongArgumentError(ex, commandLineOptions) }
                 .map(this::getConfiguration)
+                .flatMap {
+                    it.toEither {
+                        WrongArgumentError(
+                                "Unexpected error when parsing command line arguments",
+                                commandLineOptions)
+                    }
+                }
     }
 
-    protected abstract fun getConfiguration(cmdLine: CommandLine): T
+    protected abstract fun getConfiguration(cmdLine: CommandLine): Option<T>
 
     protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption, default: Int): Int =
             intValue(cmdLineOpt).getOrElse { default }
@@ -52,12 +60,19 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
     protected fun CommandLine.longValue(cmdLineOpt: CommandLineOption, default: Long): Long =
             longValue(cmdLineOpt).getOrElse { default }
 
-    protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption): Option<String> =
-            optionValue(cmdLineOpt)
-
     protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption, default: String): String =
             optionValue(cmdLineOpt).getOrElse { default }
 
+
+    protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
+            optionValue(cmdLineOpt).map(String::toInt)
+
+    protected fun CommandLine.longValue(cmdLineOpt: CommandLineOption): Option<Long> =
+            optionValue(cmdLineOpt).map(String::toLong)
+
+    protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption): Option<String> =
+            optionValue(cmdLineOpt)
+
     protected fun CommandLine.hasOption(cmdLineOpt: CommandLineOption): Boolean =
             this.hasOption(cmdLineOpt.option.opt)
 
@@ -65,10 +80,4 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
 
     private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption): Option<String> =
             Option.fromNullable(getOptionValue(cmdLineOpt.option.opt))
-
-    private fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
-            optionValue(cmdLineOpt).map(String::toInt)
-
-    private fun CommandLine.longValue(cmdLineOpt: CommandLineOption): Option<Long> =
-            optionValue(cmdLineOpt).map(String::toLong)
 }
index 1d94dc3..6180adf 100644 (file)
@@ -25,6 +25,7 @@ import org.apache.commons.cli.Option
 enum class CommandLineOption(val option: Option) {
     LISTEN_PORT(Option.builder("p")
             .longOpt("listen-port")
+            .required()
             .hasArg()
             .desc("Listen port")
             .build()
index b713baf..48f9dc5 100644 (file)
@@ -5,11 +5,8 @@ LABEL license.name="The Apache Software License, Version 2.0"
 LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
 LABEL maintainer="Nokia Wroclaw ONAP Team"
 
-EXPOSE 5000
-
 WORKDIR /opt/ves-hv-client-simulator
 ENTRYPOINT ["java", "-cp", "*:", "org.onap.dcae.collectors.veshv.simulators.xnf.MainKt"]
-CMD ["--ves-host", "ves-hv-collector", "--ves-port", "6061"]
 COPY target/libs/external/* ./
 COPY target/libs/internal/* ./
 COPY target/hv-collector-xnf-simulator-*.jar ./
  */
 package org.onap.dcae.collectors.veshv.simulators.xnf.config
 
+import arrow.core.ForOption
+import arrow.core.Option
+import arrow.core.fix
+import arrow.instances.extensions
+import arrow.typeclasses.binding
 import org.apache.commons.cli.CommandLine
 import org.apache.commons.cli.DefaultParser
 import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
@@ -30,7 +35,7 @@ import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.*
  * @author Jakub Dudycz <jakub.dudycz@nokia.com>
  * @since June 2018
  */
-internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfiguration>(DefaultParser()) {
+internal class ArgXnfSimulatorConfiguration : ArgBasedConfiguration<SimulatorConfiguration>(DefaultParser()) {
     override val cmdLineOptionsList = listOf(
             VES_HV_PORT,
             VES_HV_HOST,
@@ -41,17 +46,20 @@ internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfigu
             TRUST_CERT_FILE
     )
 
-    override fun getConfiguration(cmdLine: CommandLine): SimulatorConfiguration {
-        val vesHost = cmdLine.stringValue(VES_HV_HOST, DefaultValues.VES_HV_HOST)
-        val vesPort = cmdLine.intValue(VES_HV_PORT, DefaultValues.VES_HV_PORT)
-        val listenPort = cmdLine.intValue(LISTEN_PORT, DefaultValues.LISTEN_PORT)
+    override fun getConfiguration(cmdLine: CommandLine): Option<SimulatorConfiguration> =
+            ForOption extensions {
+                binding {
+                    val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
+                    val vesHost = cmdLine.stringValue(VES_HV_HOST).bind()
+                    val vesPort = cmdLine.intValue(VES_HV_PORT).bind()
 
-        return SimulatorConfiguration(
-                listenPort,
-                vesHost,
-                vesPort,
-                parseSecurityConfig(cmdLine))
-    }
+                    SimulatorConfiguration(
+                            listenPort,
+                            vesHost,
+                            vesPort,
+                            parseSecurityConfig(cmdLine))
+                }.fix()
+            }
 
     private fun parseSecurityConfig(cmdLine: CommandLine): SecurityConfiguration {
         val sslDisable = cmdLine.hasOption(SSL_DISABLE)
@@ -70,8 +78,5 @@ internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfigu
         const val PRIVATE_KEY_FILE = "/etc/ves-hv/client.key"
         const val CERT_FILE = "/etc/ves-hv/client.crt"
         const val TRUST_CERT_FILE = "/etc/ves-hv/trust.crt"
-        const val VES_HV_PORT = 6061
-        const val VES_HV_HOST = "veshvcollector"
-        const val LISTEN_PORT = 6062
     }
 }
index a47cef5..19c52ef 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.onap.dcae.collectors.veshv.simulators.xnf
 
-import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgXnfSimulatorConfiguration
 import org.onap.dcae.collectors.veshv.simulators.xnf.impl.HttpServer
 import org.onap.dcae.collectors.veshv.simulators.xnf.impl.XnfSimulator
 import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure
@@ -36,7 +36,7 @@ const val PROGRAM_NAME = "java $PACKAGE_NAME.MainKt"
  * @author Jakub Dudycz <jakub.dudycz@nokia.com>
  * @since June 2018
  */
-fun main(args: Array<String>) = ArgConfigurationProvider().parse(args)
+fun main(args: Array<String>) = ArgXnfSimulatorConfiguration().parse(args)
         .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME))
         .map {
             XnfSimulator(it)
@@ -20,6 +20,7 @@
 package org.onap.dcae.collectors.veshv.main.config
 
 import arrow.core.identity
+import org.assertj.core.api.Assertions
 import org.assertj.core.api.Assertions.assertThat
 import org.jetbrains.spek.api.Spek
 import org.jetbrains.spek.api.dsl.describe
@@ -27,22 +28,25 @@ 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.domain.SecurityConfiguration
-import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider
-import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider.DefaultValues
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgXnfSimulatorConfiguration
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgXnfSimulatorConfiguration.DefaultValues
 import org.onap.dcae.collectors.veshv.simulators.xnf.config.SimulatorConfiguration
+import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError
 import java.nio.file.Paths
 import kotlin.test.assertTrue
 
 
-object ArgConfigurationProviderTest : Spek({
-    lateinit var cut: ArgConfigurationProvider
-    val vesHost = "localhosting"
+object ArgXnfSimulatorConfiurationTest : Spek({
+    lateinit var cut: ArgXnfSimulatorConfiguration
+    val listenPort = "4321"
+    val vesHost = "localhost"
+    val vesPort = "1234"
     val pk = Paths.get("/", "etc", "ves", "pk.pem")
     val cert = Paths.get("/", "etc", "ssl", "certs", "ca-bundle.crt")
     val trustCert = Paths.get("/", "etc", "ves", "trusted.crt")
 
     beforeEachTest {
-        cut = ArgConfigurationProvider()
+        cut = ArgXnfSimulatorConfiguration()
     }
 
     fun parse(vararg cmdLine: String): SimulatorConfiguration =
@@ -51,6 +55,12 @@ object ArgConfigurationProviderTest : Spek({
                     ::identity
             )
 
+    fun parseExpectingFailure(vararg cmdLine: String) =
+            cut.parse(cmdLine).fold(
+                    ::identity,
+                    { throw AssertionError("parsing should have failed") }
+            )
+
     describe("parsing arguments") {
         lateinit var result: SimulatorConfiguration
 
@@ -58,15 +68,24 @@ object ArgConfigurationProviderTest : Spek({
 
             beforeEachTest {
                 result = parse("--ssl-disable",
-                        "--ves-port", "6969",
+                        "--listen-port", listenPort,
                         "--ves-host", vesHost,
+                        "--ves-port", vesPort,
                         "--private-key-file", pk.toFile().absolutePath,
                         "--cert-file", cert.toFile().absolutePath,
                         "--trust-cert-file", trustCert.toFile().absolutePath)
             }
 
-            it("should set proper port") {
-                assertThat(result.vesPort).isEqualTo(6969)
+            it("should set proper listen port") {
+                assertThat(result.listenPort).isEqualTo(listenPort.toInt())
+            }
+
+            it("should set proper ves host") {
+                assertThat(result.vesHost).isEqualTo(vesHost)
+            }
+
+            it("should set proper ves port") {
+                assertThat(result.vesPort).isEqualTo(vesPort.toInt())
             }
 
             it("should set proper security configuration") {
@@ -79,18 +98,26 @@ object ArgConfigurationProviderTest : Spek({
         given("some parameters are present in the short form") {
 
             beforeEachTest {
-                result = parse("-h", "ves-hv", "--ves-port", "666")
+                result = parse("-p", listenPort, "-h", vesHost, "--ves-port", vesPort)
+            }
+
+            it("should set proper listen port") {
+                assertThat(result.listenPort).isEqualTo(listenPort.toInt())
+            }
+
+            it("should set proper ves host") {
+                assertThat(result.vesHost).isEqualTo(vesHost)
             }
 
-            it("should set proper port") {
-                assertThat(result.vesPort).isEqualTo(666)
+            it("should set proper ves port") {
+                assertThat(result.vesPort).isEqualTo(vesPort.toInt())
             }
         }
 
         given("all optional parameters are absent") {
 
             beforeEachTest {
-                result = parse("-h", "ves-hv", "-v", "666")
+                result = parse("-p", listenPort, "-h", vesHost, "-v", vesPort)
             }
 
             on("security config") {
@@ -113,6 +140,7 @@ object ArgConfigurationProviderTest : Spek({
         given("disabled ssl certs together with all other parameters") {
             beforeEachTest {
                 result = parse("--ssl-disable",
+                        "--listen-port", listenPort,
                         "--ves-port", "888",
                         "--ves-host", vesHost,
                         "--private-key-file", pk.toFile().absolutePath,
@@ -138,5 +166,28 @@ object ArgConfigurationProviderTest : Spek({
                 }
             }
         }
+
+        describe("required parameter is absent") {
+            given("ves port is missing") {
+                it("should throw exception") {
+                    assertThat(parseExpectingFailure("-p", listenPort, "-h", vesHost))
+                            .isInstanceOf(WrongArgumentError::class.java)
+                }
+            }
+
+            given("ves host is missing") {
+                it("should throw exception") {
+                    assertThat(parseExpectingFailure("-p", listenPort, "-v", vesPort))
+                            .isInstanceOf(WrongArgumentError::class.java)
+                }
+            }
+
+            given("listen port is missing") {
+                it("should throw exception") {
+                    assertThat(parseExpectingFailure("-h", vesHost, "-v", vesPort))
+                            .isInstanceOf(WrongArgumentError::class.java)
+                }
+            }
+        }
     }
 })