Use SSL for encrypting the connection

Netty's OpenSSL bindings are used

Closes ONAP-179

Change-Id: I8249fbaaed1dd869b733db04a27cebf53962c80c
Issue-ID: DCAEGEN2-601
Signed-off-by: Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
diff --git a/hv-collector-main/Dockerfile b/hv-collector-main/Dockerfile
index 84ffb43..749edb8 100644
--- a/hv-collector-main/Dockerfile
+++ b/hv-collector-main/Dockerfile
@@ -5,11 +5,12 @@
 LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
 LABEL maintainer="Nokia Wroclaw ONAP Team"
 
-EXPOSE 8081
+EXPOSE 6061
 
 WORKDIR /opt/ves-hv-collector
+VOLUME /etc/ves-hv/
 ENTRYPOINT ["java", "-cp", "*:", "org.onap.dcae.collectors.veshv.main.MainKt"]
-CMD ["--listen-port", "8081", "--config-url", ""]
+CMD ["--listen-port", "6061"]
 COPY target/libs/external/* ./
 COPY target/libs/internal/* ./
 COPY target/hv-collector-main-*.jar ./
\ No newline at end of file
diff --git a/hv-collector-main/pom.xml b/hv-collector-main/pom.xml
index 80d7233..58fc5d7 100644
--- a/hv-collector-main/pom.xml
+++ b/hv-collector-main/pom.xml
@@ -19,8 +19,8 @@
   ~ ============LICENSE_END=========================================================
   -->
 <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">
+        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>
@@ -55,43 +55,60 @@
                 <artifactId>maven-surefire-plugin</artifactId>
                 <groupId>org.apache.maven.plugins</groupId>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>copy-internal-deps</id>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>copy-dependencies</goal>
-                        </goals>
-                        <configuration>
-                            <outputDirectory>${project.build.directory}/libs/internal</outputDirectory>
-                            <includeGroupIds>${project.parent.groupId}</includeGroupIds>
-                            <includeScope>runtime</includeScope>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>copy-external-deps</id>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>copy-dependencies</goal>
-                        </goals>
-                        <configuration>
-                            <outputDirectory>${project.build.directory}/libs/external</outputDirectory>
-                            <excludeGroupIds>${project.parent.groupId}</excludeGroupIds>
-                            <includeScope>runtime</includeScope>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>io.fabric8</groupId>
-                <artifactId>docker-maven-plugin</artifactId>
-            </plugin>
         </plugins>
     </build>
 
+    <profiles>
+        <profile>
+            <id>docker</id>
+            <activation>
+                <property>
+                    <name>!skipDocker</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-internal-deps</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-dependencies</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${project.build.directory}/libs/internal</outputDirectory>
+                                    <includeGroupIds>${project.parent.groupId}</includeGroupIds>
+                                    <includeScope>runtime</includeScope>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>copy-external-deps</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy-dependencies</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${project.build.directory}/libs/external</outputDirectory>
+                                    <excludeGroupIds>${project.parent.groupId}</excludeGroupIds>
+                                    <includeScope>runtime</includeScope>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--
+                    <plugin>
+                        <groupId>io.fabric8</groupId>
+                        <artifactId>docker-maven-plugin</artifactId>
+                    </plugin>
+                    -->
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
     <dependencies>
         <dependency>
             <groupId>${project.parent.groupId}</groupId>
@@ -111,6 +128,12 @@
             <groupId>commons-cli</groupId>
             <artifactId>commons-cli</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-tcnative-boringssl-static</artifactId>
+            <scope>runtime</scope>
+            <classifier>${os.detected.classifier}</classifier>
+        </dependency>
 
         <dependency>
             <groupId>org.assertj</groupId>
@@ -128,6 +151,14 @@
             <groupId>org.jetbrains.spek</groupId>
             <artifactId>spek-junit-platform-engine</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.nhaarman</groupId>
+            <artifactId>mockito-kotlin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
     </dependencies>
 
 
diff --git a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt
index 4e614cd..5689a3e 100644
--- a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt
+++ b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt
@@ -20,54 +20,55 @@
 package org.onap.dcae.collectors.veshv.main
 
 import org.apache.commons.cli.*
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
 import org.onap.dcae.collectors.veshv.domain.ServerConfiguration
+import java.io.File
+import java.nio.file.Paths
 
 internal object DefaultValues {
-    const val PORT = 8600
+    const val PORT = 6061
     const val CONFIG_URL = ""
+    const val PRIVATE_KEY_FILE = "/etc/ves-hv/server.key"
+    const val CERT_FILE = "/etc/ves-hv/server.crt"
+    const val TRUST_CERT_FILE = "/etc/ves-hv/trust.crt"
 }
 
-internal object ArgBasedServerConfiguration {
-    private val OPT_PORT = Option.builder("p")
-            .longOpt("listen-port")
-            .hasArg()
-            .desc("Listen port")
-            .build()
-
-    private val OPT_CONFIG_URL = Option.builder("c")
-            .longOpt("config-url")
-            .optionalArg(true)
-            .hasArg()
-            .desc("Url of ves configuration on consul")
-            .build()
-
-    private val options by lazy {
-        val options = Options()
-        options.addOption(OPT_PORT)
-        options.addOption(OPT_CONFIG_URL)
-        options
-    }
+internal class ArgBasedServerConfiguration {
 
     fun parse(args: Array<out String>): ServerConfiguration {
         val parser = DefaultParser()
 
         try {
-            parser.parse(options, args).run {
-                return ServerConfiguration(
-                        stringValue(OPT_CONFIG_URL, DefaultValues.CONFIG_URL),
-                        intValue(OPT_PORT, DefaultValues.PORT))
-            }
+            val cmdLine = parser.parse(options, args)
+            val port = cmdLine.intValue(OPT_PORT, DefaultValues.PORT)
+            val configUrl = cmdLine.stringValue(OPT_CONFIG_URL, DefaultValues.CONFIG_URL)
+            val secConf = createSecurityConfiguration(cmdLine)
+            return ServerConfiguration(port, configUrl, secConf)
         } catch (ex: Exception) {
             throw WrongArgumentException(ex)
         }
     }
 
+    private fun createSecurityConfiguration(cmdLine: CommandLine): SecurityConfiguration {
+
+        val pkFile = cmdLine.stringValue(OPT_PK_FILE, DefaultValues.PRIVATE_KEY_FILE)
+        val certFile = cmdLine.stringValue(OPT_CERT_FILE, DefaultValues.CERT_FILE)
+        val trustCertFile = cmdLine.stringValue(OPT_TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE)
+
+        return SecurityConfiguration(
+                privateKey = stringPathToPath(pkFile),
+                cert = stringPathToPath(certFile),
+                trustedCert = stringPathToPath(trustCertFile)
+        )
+    }
+
     private fun CommandLine.intValue(option: Option, default: Int) =
             getOptionValue(option.opt)?.toInt() ?: default
 
     private fun CommandLine.stringValue(option: Option, default: String) =
             getOptionValue(option.opt) ?: default
 
+    private fun stringPathToPath(path: String) = Paths.get(File(path).toURI())
 
     class WrongArgumentException(parent: Exception) : Exception(parent.message, parent) {
         fun printMessage() {
@@ -79,4 +80,46 @@
             formatter.printHelp(programName, options)
         }
     }
+
+    companion object {
+        private val OPT_PORT = Option.builder("p")
+                .longOpt("listen-port")
+                .hasArg()
+                .desc("Listen port")
+                .build()
+
+        private val OPT_CONFIG_URL = Option.builder("c")
+                .longOpt("config-url")
+                .hasArg()
+                .desc("URL of ves configuration on consul")
+                .build()
+
+        private val OPT_PK_FILE = Option.builder("k")
+                .longOpt("private-key-file")
+                .hasArg()
+                .desc("File with private key in PEM format")
+                .build()
+
+        private val OPT_CERT_FILE = Option.builder("e")
+                .longOpt("cert-file")
+                .hasArg()
+                .desc("File with server certificate bundle")
+                .build()
+
+        private val OPT_TRUST_CERT_FILE = Option.builder("t")
+                .longOpt("trust-cert-file")
+                .hasArg()
+                .desc("File with trusted certificate bundle for authenticating clients")
+                .build()
+
+        private val options by lazy {
+            val options = Options()
+            options.addOption(OPT_PORT)
+            options.addOption(OPT_CONFIG_URL)
+            options.addOption(OPT_PK_FILE)
+            options.addOption(OPT_CERT_FILE)
+            options.addOption(OPT_TRUST_CERT_FILE)
+            options
+        }
+    }
 }
diff --git a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt
index d81a063..3685250 100644
--- a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt
+++ b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt
@@ -35,7 +35,7 @@
 
 fun main(args: Array<String>) {
     try {
-        val serverConfiguration = ArgBasedServerConfiguration.parse(args)
+        val serverConfiguration = ArgBasedServerConfiguration().parse(args)
 
         val collectorProvider = CollectorFactory(
                 resolveConfigurationProvider(serverConfiguration),
diff --git a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt
index 0d2188c..6eec577 100644
--- a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt
+++ b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt
@@ -23,31 +23,60 @@
 import org.jetbrains.spek.api.Spek
 import org.jetbrains.spek.api.dsl.given
 import org.jetbrains.spek.api.dsl.it
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.domain.ServerConfiguration
+import java.nio.file.Paths
 
 /**
  * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
  * @since May 2018
  */
 object ArgBasedServerConfigurationTest : Spek({
-    val cut = ArgBasedServerConfiguration
+    lateinit var cut: ArgBasedServerConfiguration
     val configurationUrl = "http://test-address/test"
+    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 = ArgBasedServerConfiguration()
+    }
 
     fun parse(vararg cmdLine: String) = cut.parse(cmdLine)
 
     given("all parameters are present in the long form") {
-        val result = parse("--listen-port", "6969", "--config-url", configurationUrl)
+        lateinit var result: ServerConfiguration
+
+        beforeEachTest {
+            result = parse("--listen-port", "6969",
+                    "--config-url", configurationUrl,
+                    "--private-key-file", pk.toFile().absolutePath,
+                    "--cert-file", cert.toFile().absolutePath,
+                    "--trust-cert-file", trustCert.toFile().absolutePath)
+        }
 
         it("should set proper port") {
             assertThat(result.port).isEqualTo(6969)
         }
 
+
         it("should set proper config url") {
             assertThat(result.configurationUrl).isEqualTo(configurationUrl)
         }
+
+        it("should set proper security configuration") {
+            assertThat(result.securityConfiguration).isEqualTo(
+                    SecurityConfiguration(pk, cert, trustCert)
+            )
+        }
     }
 
-    given("all parameters are present in the short form") {
-        val result = parse("-p", "666", "-c", configurationUrl)
+    given("some parameters are present in the short form") {
+        lateinit var result: ServerConfiguration
+
+        beforeEachTest {
+            result = parse("-p", "666", "-c", configurationUrl)
+        }
 
         it("should set proper port") {
             assertThat(result.port).isEqualTo(666)
@@ -59,7 +88,11 @@
     }
 
     given("all optional parameters are absent") {
-        val result = parse()
+        lateinit var result: ServerConfiguration
+
+        beforeEachTest {
+            result = parse()
+        }
 
         it("should set default port") {
             assertThat(result.port).isEqualTo(DefaultValues.PORT)
@@ -69,4 +102,4 @@
             assertThat(result.configurationUrl).isEqualTo(DefaultValues.CONFIG_URL)
         }
     }
-})
\ No newline at end of file
+})
diff --git a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/NioBuffersTest.kt b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/NioBuffersTest.kt
index b46d5a2..42bf363 100644
--- a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/NioBuffersTest.kt
+++ b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/NioBuffersTest.kt
@@ -22,13 +22,14 @@
 import org.jetbrains.spek.api.Spek
 import org.jetbrains.spek.api.dsl.describe
 import org.jetbrains.spek.api.dsl.it
+import org.jetbrains.spek.api.dsl.xdescribe
 import java.nio.ByteBuffer
 
-fun Int.toKibibytes(): Int = this * 1024
-fun Int.toMebibytes(): Int = this * 1024 * 1024
-
-
 object NioBuffersTest : Spek({
+
+    fun Int.toKibibytes(): Int = this * 1024
+    fun Int.toMebibytes(): Int = this * 1024 * 1024
+
     val BUFFER_SIZES = listOf(128.toKibibytes(), 512.toKibibytes(), 1.toMebibytes(), 2.toMebibytes())
     val NUMBER_OF_ITERATIONS = 100
 
@@ -53,7 +54,7 @@
 
     for (singleBufferSize in BUFFER_SIZES) {
 
-        describe("$singleBufferSize bytes buffers") {
+        xdescribe("$singleBufferSize bytes buffers") {
             describe("direct buffers") {
 
                 val bb1 = ByteBuffer.allocateDirect(singleBufferSize)