aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2018-09-04 09:59:20 +0200
committerPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2018-09-04 13:18:50 +0200
commit199edc49a418ab015ad3a54a5750f1a3f485b7e7 (patch)
tree14985ad68d11d2303dca2e5a0454a9e441e915db
parentd00acee05c05c7e3146abf7d13b78953f9a0d3f9 (diff)
Read config from environment variables
The application configuration should be read from command line options as well as from environment variables. The priority: cmd-line over env over defaults. Change-Id: I785fd1fbaf66f3eab84a162f037153f1688ed791 Issue-ID: DCAEGEN2-748 Signed-off-by: Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt12
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt6
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt11
-rw-r--r--hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/CoreKtTest.kt83
-rw-r--r--hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOptionTest.kt62
5 files changed, 169 insertions, 5 deletions
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt
index 844d18d8..2d538b72 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt
@@ -20,8 +20,12 @@
package org.onap.dcae.collectors.veshv.utils.arrow
import arrow.core.Either
+import arrow.core.None
import arrow.core.Option
+import arrow.core.Some
import arrow.core.identity
+import arrow.syntax.collections.firstOption
+import java.util.*
import java.util.concurrent.atomic.AtomicReference
/**
@@ -32,3 +36,11 @@ import java.util.concurrent.atomic.AtomicReference
fun <A> Either<A, A>.flatten() = fold(::identity, ::identity)
fun <A> AtomicReference<A>.getOption() = Option.fromNullable(get())
+
+fun <A> Option.Companion.fromNullablesChain(firstValue: A?, vararg nextValues: () -> A?): Option<A> =
+ if (firstValue != null)
+ Option.just(firstValue)
+ else nextValues.asSequence()
+ .map { it() }
+ .filter { it != null }
+ .firstOption()
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
index 16634889..1ebe4e48 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
@@ -27,6 +27,7 @@ import arrow.core.getOrElse
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
import org.apache.commons.cli.Options
+import org.onap.dcae.collectors.veshv.utils.arrow.fromNullablesChain
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
@@ -77,6 +78,7 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
protected fun stringPathToPath(path: String): Path = Paths.get(File(path).toURI())
- private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption): Option<String> =
- Option.fromNullable(getOptionValue(cmdLineOpt.option.opt))
+ private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption) = Option.fromNullablesChain(
+ getOptionValue(cmdLineOpt.option.opt),
+ { System.getenv(cmdLineOpt.environmentVariableName()) })
}
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
index 836a05df..3a154db2 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
@@ -117,5 +117,14 @@ enum class CommandLineOption(val option: Option) {
.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/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/CoreKtTest.kt b/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/CoreKtTest.kt
index 585851be..29359439 100644
--- a/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/CoreKtTest.kt
+++ b/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/CoreKtTest.kt
@@ -20,6 +20,7 @@
package org.onap.dcae.collectors.veshv.utils.arrow
import arrow.core.None
+import arrow.core.Option
import arrow.core.Some
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.spek.api.Spek
@@ -27,6 +28,7 @@ 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.jetbrains.spek.api.dsl.xdescribe
import java.util.concurrent.atomic.AtomicReference
@@ -34,7 +36,7 @@ import java.util.concurrent.atomic.AtomicReference
* @author Piotr Jaszczyk <piotr.jaszczyk></piotr.jaszczyk>@nokia.com>
* @since August 2018
*/
-internal class CoreKtTest: Spek({
+internal class CoreKtTest : Spek({
describe("AtomicReference.getOption") {
given("empty atomic reference") {
val atomicReference = AtomicReference<String>()
@@ -60,4 +62,81 @@ internal class CoreKtTest: Spek({
}
}
}
-}) \ No newline at end of file
+
+ describe("Option.fromNullablesChain") {
+ given("one non-null element") {
+ val just = "some text"
+ on("calling factory") {
+ val result = Option.fromNullablesChain(just)
+
+ it("should return Some($just)") {
+ assertThat(result).isEqualTo(Some(just))
+ }
+ }
+ }
+
+ given("one null element") {
+ val just: String? = null
+ on("calling factory") {
+ val result = Option.fromNullablesChain(just)
+
+ it("should return None") {
+ assertThat(result).isEqualTo(None)
+ }
+ }
+ }
+
+ given("first non-null element") {
+ val first = "some text"
+ val second: String? = null
+ var secondAskedForValue = false
+ on("calling factory") {
+ val result = Option.fromNullablesChain(first, { secondAskedForValue = true; second })
+
+ it("should return Some($first)") {
+ assertThat(result).isEqualTo(Some(first))
+ }
+
+ it("should have not called second provider (should be lazy)") {
+ assertThat(secondAskedForValue).isFalse()
+ }
+ }
+ }
+
+ given("two non-null elements") {
+ val first = "some text"
+ val second = "another text"
+ on("calling factory") {
+ val result = Option.fromNullablesChain(first, { second })
+
+ it("should return Some($first)") {
+ assertThat(result).isEqualTo(Some(first))
+ }
+ }
+ }
+
+ given("two null elements") {
+ val first: String? = null
+ val second: String? = null
+ on("calling factory") {
+ val result = Option.fromNullablesChain(first, { second })
+
+ it("should return None") {
+ assertThat(result).isEqualTo(None)
+ }
+ }
+ }
+
+ given("second non-null element") {
+ val first: String? = null
+ val second = "another text"
+ on("calling factory") {
+ val result = Option.fromNullablesChain(first, { second })
+
+ it("should return Some($second)") {
+ assertThat(result).isEqualTo(Some(second))
+ }
+ }
+ }
+ }
+})
diff --git a/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOptionTest.kt b/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOptionTest.kt
new file mode 100644
index 00000000..f36df043
--- /dev/null
+++ b/hv-collector-utils/src/test/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOptionTest.kt
@@ -0,0 +1,62 @@
+/*
+ * ============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.utils.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
+
+/**
+ * @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 = CommandLineOption.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 = CommandLineOption.DUMMY_MODE
+
+ on("calling environmentVariableName") {
+ val result = opt.environmentVariableName()
+
+ it("should return prefixed upper snake cased long option name") {
+ assertThat(result).isEqualTo("VESHV_DUMMY")
+ }
+ }
+ }
+ }
+ }
+})