Create health check module 01/59601/4
authorJakub Dudycz <jakub.dudycz@nokia.com>
Tue, 7 Aug 2018 12:18:37 +0000 (14:18 +0200)
committerJakub Dudycz <jakub.dudycz@nokia.com>
Wed, 8 Aug 2018 12:51:38 +0000 (14:51 +0200)
Create ves-hv-collector-health-check module with dummy api server and connect it with ves-hv-collector-main
This is a preparation for health check mechanism implementation

Change-Id: I2f668ab7337b1ed7e2afea6c56f34880de3ef1b5
Issue-ID: DCAEGEN2-659
Signed-off-by: Jakub Dudycz <jakub.dudycz@nokia.com>
docker-compose.yml
hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/model/ServerConfiguration.kt
hv-collector-health-check/pom.xml [new file with mode: 0644]
hv-collector-health-check/src/main/kotlin/org/onap/dcae/collectors/veshv/healthcheck/http/HealthCheckApiServer.kt [new file with mode: 0644]
hv-collector-main/pom.xml
hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt
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
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
pom.xml

index f0713c7..7bd84f5 100644 (file)
@@ -34,6 +34,7 @@ services:
 #      context: hv-collector-main
 #      dockerfile: Dockerfile
     ports:
+      - "6060:6060"
       - "6061:6061/tcp"
     command: ["--listen-port", "6061","--config-url", "http://consul:8500/v1/kv/veshv-config"]
     depends_on:
index b0f3ec0..c14d36e 100644 (file)
@@ -31,4 +31,5 @@ data class ServerConfiguration(
         val configurationProviderParams: ConfigurationProviderParams,
         val securityConfiguration: SecurityConfiguration,
         val idleTimeout: Duration,
+        val healthCheckApiPort: Int,
         val dummyMode: Boolean = false)
diff --git a/hv-collector-health-check/pom.xml b/hv-collector-health-check/pom.xml
new file mode 100644 (file)
index 0000000..4072ec2
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+        </license>
+    </licenses>
+
+    <properties>
+        <skipAnalysis>false</skipAnalysis>
+        <failIfMissingUnitTests>false</failIfMissingUnitTests>
+    </properties>
+
+    <parent>
+        <groupId>org.onap.dcaegen2.collectors.veshv</groupId>
+        <artifactId>ves-hv-collector</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>hv-collector-health-check</artifactId>
+    <description>VES HighVolume Collector :: Health check</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <groupId>org.jetbrains.kotlin</groupId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <groupId>org.apache.maven.plugins</groupId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-stdlib-jdk8</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.ratpack</groupId>
+            <artifactId>ratpack-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.arrow-kt</groupId>
+            <artifactId>arrow-effects</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/hv-collector-health-check/src/main/kotlin/org/onap/dcae/collectors/veshv/healthcheck/http/HealthCheckApiServer.kt b/hv-collector-health-check/src/main/kotlin/org/onap/dcae/collectors/veshv/healthcheck/http/HealthCheckApiServer.kt
new file mode 100644 (file)
index 0000000..9cab031
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * ============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.healthcheck.http
+
+import arrow.effects.IO
+import ratpack.handling.Chain
+import ratpack.http.Status
+import ratpack.server.RatpackServer
+import ratpack.server.ServerConfig
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since August 2018
+ */
+class HealthCheckApiServer {
+
+    fun start(port: Int): IO<RatpackServer> = IO {
+        RatpackServer
+                .start {
+                    it
+                            .serverConfig(ServerConfig.embedded().port(port).development(false))
+                            .handlers(this::configureHandlers)
+                }
+    }
+
+    private fun configureHandlers(chain: Chain) {
+        chain
+                .get("healthcheck") { ctx ->
+                    ctx.response.status(Status.OK).send()
+                }
+    }
+}
\ No newline at end of file
index e594aef..0e95628 100644 (file)
             <artifactId>hv-collector-core</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+        <dependency>
+            <groupId>${project.parent.groupId}</groupId>
+            <artifactId>hv-collector-health-check</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
         <dependency>
             <groupId>${project.parent.groupId}</groupId>
             <artifactId>hv-collector-test-utils</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>io.ratpack</groupId>
+            <artifactId>ratpack-core</artifactId>
+        </dependency>
         <dependency>
             <groupId>io.arrow-kt</groupId>
             <artifactId>arrow-core</artifactId>
index 7c958b9..26230cd 100644 (file)
@@ -35,6 +35,7 @@ import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL_FIRST_REQUEST_DELAY
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL_REQUEST_INTERVAL
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.DUMMY_MODE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.HEALTH_CHECK_API_PORT
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.IDLE_TIMEOUT_SEC
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.LISTEN_PORT
 import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.PRIVATE_KEY_FILE
@@ -44,6 +45,7 @@ import java.time.Duration
 
 internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration>(DefaultParser()) {
     override val cmdLineOptionsList = listOf(
+            HEALTH_CHECK_API_PORT,
             LISTEN_PORT,
             CONSUL_CONFIG_URL,
             CONSUL_FIRST_REQUEST_DELAY,
@@ -59,12 +61,17 @@ internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration
     override fun getConfiguration(cmdLine: CommandLine): Option<ServerConfiguration> =
             ForOption extensions {
                 binding {
+                    val healthCheckApiPort = cmdLine.intValue(
+                            HEALTH_CHECK_API_PORT,
+                            DefaultValues.HEALTH_CHECK_API_PORT
+                    )
                     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).bind()
                     ServerConfiguration(
+                            healthCheckApiPort = healthCheckApiPort,
                             listenPort = listenPort,
                             configurationProviderParams = configurationProviderParams,
                             securityConfiguration = security,
@@ -77,9 +84,14 @@ internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration
             ForOption extensions {
                 binding {
                     val configUrl = cmdLine.stringValue(CONSUL_CONFIG_URL).bind()
-                    val firstRequestDelay = cmdLine.longValue(CONSUL_FIRST_REQUEST_DELAY, DefaultValues.CONSUL_FIRST_REQUEST_DELAY)
-                    val requestInterval = cmdLine.longValue(CONSUL_REQUEST_INTERVAL, DefaultValues.CONSUL_REQUEST_INTERVAL)
-
+                    val firstRequestDelay = cmdLine.longValue(
+                            CONSUL_FIRST_REQUEST_DELAY,
+                            DefaultValues.CONSUL_FIRST_REQUEST_DELAY
+                    )
+                    val requestInterval = cmdLine.longValue(
+                            CONSUL_REQUEST_INTERVAL,
+                            DefaultValues.CONSUL_REQUEST_INTERVAL
+                    )
                     ConfigurationProviderParams(
                             configUrl,
                             Duration.ofSeconds(firstRequestDelay),
@@ -103,6 +115,7 @@ internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration
     }
 
     internal object DefaultValues {
+        const val HEALTH_CHECK_API_PORT = 6060
         const val CONSUL_FIRST_REQUEST_DELAY = 10L
         const val CONSUL_REQUEST_INTERVAL = 5L
         const val PRIVATE_KEY_FILE = "/etc/ves-hv/server.key"
index 44d09d4..23d7d2e 100644 (file)
@@ -23,6 +23,7 @@ import org.onap.dcae.collectors.veshv.boundary.Server
 import org.onap.dcae.collectors.veshv.boundary.ServerHandle
 import org.onap.dcae.collectors.veshv.factory.CollectorFactory
 import org.onap.dcae.collectors.veshv.factory.ServerFactory
+import org.onap.dcae.collectors.veshv.healthcheck.http.HealthCheckApiServer
 import org.onap.dcae.collectors.veshv.impl.adapters.AdapterFactory
 import org.onap.dcae.collectors.veshv.model.ServerConfiguration
 import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure
@@ -36,6 +37,7 @@ private const val PROGRAM_NAME = "java org.onap.dcae.collectors.veshv.main.MainK
 fun main(args: Array<String>) =
         ArgVesHvConfiguration().parse(args)
                 .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME))
+                .map(::startHealthCheckApiServer)
                 .map(::createServer)
                 .map {
                     it.start()
@@ -50,7 +52,6 @@ fun main(args: Array<String>) =
                         { logger.info("Gentle shutdown") }
                 )
 
-
 private fun createServer(config: ServerConfiguration): Server {
     val sink = if (config.dummyMode) AdapterFactory.loggingSink() else AdapterFactory.kafkaSink()
     val collectorProvider = CollectorFactory(
@@ -62,7 +63,13 @@ private fun createServer(config: ServerConfiguration): Server {
     return ServerFactory.createNettyTcpServer(config, collectorProvider)
 }
 
-private fun logServerStarted(handle: ServerHandle): ServerHandle {
-    logger.info("HighVolume VES Collector is up and listening on ${handle.host}:${handle.port}")
-    return handle
+private fun logServerStarted(handle: ServerHandle): ServerHandle = handle.also {
+    logger.info("HighVolume VES Collector is up and listening on ${it.host}:${it.port}")
+}
+
+private fun startHealthCheckApiServer(config: ServerConfiguration): ServerConfiguration = config.apply {
+    HealthCheckApiServer()
+            .start(healthCheckApiPort)
+            .unsafeRunSync()
+            .also { logger.info("Health check api server started on port ${it.bindPort}") }
 }
index 14f9be0..2650719 100644 (file)
@@ -40,6 +40,7 @@ import java.time.Duration
  */
 object ArgVesHvConfigurationTest : Spek({
     lateinit var cut: ArgVesHvConfiguration
+    val healthCheckApiPort = "6070"
     val configurationUrl = "http://test-address/test"
     val firstRequestDelay = "10"
     val requestInterval = "5"
@@ -58,6 +59,7 @@ object ArgVesHvConfigurationTest : Spek({
 
             beforeEachTest {
                 result = cut.parseExpectingSuccess("--ssl-disable",
+                        "--health-check-api-port", healthCheckApiPort,
                         "--listen-port", listenPort,
                         "--config-url", configurationUrl,
                         "--first-request-delay", firstRequestDelay,
@@ -67,7 +69,11 @@ object ArgVesHvConfigurationTest : Spek({
                         "--trust-cert-file", trustCert.toFile().absolutePath)
             }
 
-            it("should set proper port") {
+            it("should set proper health check api port") {
+                assertThat(result.healthCheckApiPort).isEqualTo(healthCheckApiPort.toInt())
+            }
+
+            it("should set proper listen port") {
                 assertThat(result.listenPort).isEqualTo(listenPort.toInt())
             }
 
index c00ce68..1663488 100644 (file)
@@ -60,6 +60,9 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
     protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption, default: String): String =
             optionValue(cmdLineOpt).getOrElse { default }
 
+    protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption, default: Int): Int =
+            intValue(cmdLineOpt).getOrElse { default }
+
     protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
             optionValue(cmdLineOpt).map(String::toInt)
 
index 44de9d7..836a05d 100644 (file)
@@ -23,6 +23,12 @@ import org.apache.commons.cli.Option
 
 
 enum class CommandLineOption(val option: Option) {
+    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")
             .required()
diff --git a/pom.xml b/pom.xml
index cf5d5ad..19b9892 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <module>hv-collector-ct</module>
         <module>hv-collector-dcae-app-simulator</module>
         <module>hv-collector-domain</module>
+        <module>hv-collector-health-check</module>
         <module>hv-collector-main</module>
+        <module>hv-collector-test-utils</module>
         <module>hv-collector-utils</module>
         <module>hv-collector-ves-message-generator</module>
         <module>hv-collector-xnf-simulator</module>
-        <module>hv-collector-test-utils</module>
     </modules>
 
     <properties>