aboutsummaryrefslogtreecommitdiffstats
path: root/hv-collector-xnf-simulator
diff options
context:
space:
mode:
authorJakub Dudycz <jdudycz@nokia.com>2018-07-09 08:06:01 +0200
committerPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2018-08-02 12:59:58 +0200
commit1383775f3df00bd08a7ac14fe1278858bdef6487 (patch)
tree0a4e02fe2dc25447967b824b21a1e0bfc81c0b38 /hv-collector-xnf-simulator
parentaf92961d8e79769dbd70340ab661f7a42b783435 (diff)
Rename hv-collector-client-simulator
New name: hv-collector-xnf-simulator Closes ONAP-492 Change-Id: I161dda0d01e90bfe35e5e2d575ec9e81cc8bf3c3 Signed-off-by: Jakub Dudycz <jdudycz@nokia.com> Issue-ID: DCAEGEN2-601
Diffstat (limited to 'hv-collector-xnf-simulator')
-rw-r--r--hv-collector-xnf-simulator/Dockerfile15
-rw-r--r--hv-collector-xnf-simulator/pom.xml162
-rw-r--r--hv-collector-xnf-simulator/sample-request.json20
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/api/MessageGenerator.kt32
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt77
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/MessageParameters.kt28
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/SimulatorConfiguration.kt32
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/factory.kt30
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/HttpServer.kt116
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageGeneratorImpl.kt79
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGenerator.kt62
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/XnfSimulator.kt121
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt53
-rw-r--r--hv-collector-xnf-simulator/src/main/resources/logback.xml35
-rw-r--r--hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt126
-rw-r--r--hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageFactoryTest.kt83
-rw-r--r--hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGeneratorTest.kt74
17 files changed, 1145 insertions, 0 deletions
diff --git a/hv-collector-xnf-simulator/Dockerfile b/hv-collector-xnf-simulator/Dockerfile
new file mode 100644
index 00000000..b713bafc
--- /dev/null
+++ b/hv-collector-xnf-simulator/Dockerfile
@@ -0,0 +1,15 @@
+FROM openjdk:10-jre-slim
+
+LABEL copyright="Copyright (C) 2018 NOKIA"
+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 ./
diff --git a/hv-collector-xnf-simulator/pom.xml b/hv-collector-xnf-simulator/pom.xml
new file mode 100644
index 00000000..9af2246d
--- /dev/null
+++ b/hv-collector-xnf-simulator/pom.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ ============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=========================================================
+ -->
+<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>
+
+ <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-xnf-simulator</artifactId>
+ <description>VES HighVolume Collector :: XNF simulator</description>
+
+ <properties>
+ <skipAnalysis>false</skipAnalysis>
+ <docker-image.name>ves-hv-collector-xnf-simulator</docker-image.name>
+ </properties>
+
+ <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>
+ <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>
+ </plugin>
+ <!-- TODO: unskip docker
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ </plugin>
+ -->
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-domain</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-utils</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.arrow-kt</groupId>
+ <artifactId>arrow-effects</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-jdk8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-tcnative-boringssl-static</artifactId>
+ <scope>runtime</scope>
+ <classifier>${os.detected.classifier}</classifier>
+ </dependency>
+ <dependency>
+ <groupId>com.nhaarman</groupId>
+ <artifactId>mockito-kotlin</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.spek</groupId>
+ <artifactId>spek-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.spek</groupId>
+ <artifactId>spek-junit-platform-engine</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.projectreactor</groupId>
+ <artifactId>reactor-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.ratpack</groupId>
+ <artifactId>ratpack-core</artifactId>
+ </dependency>
+ </dependencies>
+
+
+</project> \ No newline at end of file
diff --git a/hv-collector-xnf-simulator/sample-request.json b/hv-collector-xnf-simulator/sample-request.json
new file mode 100644
index 00000000..ca8bd885
--- /dev/null
+++ b/hv-collector-xnf-simulator/sample-request.json
@@ -0,0 +1,20 @@
+{
+ "commonEventHeader": {
+ "version": "sample-version",
+ "domain": 10,
+ "sequence": 1,
+ "priority": 1,
+ "eventId": "sample-event-id",
+ "eventName": "sample-event-name",
+ "eventType": "sample-event-type",
+ "startEpochMicrosec": 120034455,
+ "lastEpochMicrosec": 120034455,
+ "nfNamingCode": "sample-nf-naming-code",
+ "nfcNamingCode": "sample-nfc-naming-code",
+ "reportingEntityId": "sample-reporting-entity-id",
+ "reportingEntityName": "sample-reporting-entity-name",
+ "sourceId": "sample-source-id",
+ "sourceName": "sample-source-name"
+ },
+ "messagesAmount": 25000
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/api/MessageGenerator.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/api/MessageGenerator.kt
new file mode 100644
index 00000000..f4c92fd4
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/api/MessageGenerator.kt
@@ -0,0 +1,32 @@
+/*
+ * ============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.simulators.xnf.api
+
+import org.onap.dcae.collectors.veshv.domain.WireFrame
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.MessageParameters
+import reactor.core.publisher.Flux
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since June 2018
+ */
+interface MessageGenerator {
+ fun createMessageFlux(messageParameters: MessageParameters): Flux<WireFrame>
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt
new file mode 100644
index 00000000..04654f8c
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt
@@ -0,0 +1,77 @@
+/*
+ * ============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.simulators.xnf.config
+
+import org.apache.commons.cli.CommandLine
+import org.apache.commons.cli.DefaultParser
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CERT_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.MESSAGES_TO_SEND_AMOUNT
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.PRIVATE_KEY_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_CERT_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_HOST
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_PORT
+
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfiguration>(DefaultParser()) {
+ override val cmdLineOptionsList = listOf(
+ VES_HV_PORT,
+ VES_HV_HOST,
+ MESSAGES_TO_SEND_AMOUNT,
+ PRIVATE_KEY_FILE,
+ CERT_FILE,
+ TRUST_CERT_FILE
+ )
+
+ override fun getConfiguration(cmdLine: CommandLine): SimulatorConfiguration {
+ val host = cmdLine.stringValue(VES_HV_HOST, DefaultValues.VES_HV_HOST)
+ val port = cmdLine.intValue(VES_HV_PORT, DefaultValues.VES_HV_PORT)
+ val messagesAmount = cmdLine.longValue(MESSAGES_TO_SEND_AMOUNT, DefaultValues.MESSAGES_AMOUNT)
+ return SimulatorConfiguration(
+ host,
+ port,
+ parseSecurityConfig(cmdLine),
+ messagesAmount)
+ }
+
+ private fun parseSecurityConfig(cmdLine: CommandLine): SecurityConfiguration {
+ val pkFile = cmdLine.stringValue(PRIVATE_KEY_FILE, DefaultValues.PRIVATE_KEY_FILE)
+ val certFile = cmdLine.stringValue(CERT_FILE, DefaultValues.CERT_FILE)
+ val trustCertFile = cmdLine.stringValue(TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE)
+ return SecurityConfiguration(
+ privateKey = stringPathToPath(pkFile),
+ cert = stringPathToPath(certFile),
+ trustedCert = stringPathToPath(trustCertFile))
+ }
+
+ internal object DefaultValues {
+ const val MESSAGES_AMOUNT = -1L
+ 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"
+ }
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/MessageParameters.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/MessageParameters.kt
new file mode 100644
index 00000000..f993f45a
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/MessageParameters.kt
@@ -0,0 +1,28 @@
+/*
+ * ============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.simulators.xnf.config
+
+import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+data class MessageParameters(val commonEventHeader: CommonEventHeader, val amount: Long = -1)
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/SimulatorConfiguration.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/SimulatorConfiguration.kt
new file mode 100644
index 00000000..1052cfcc
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/SimulatorConfiguration.kt
@@ -0,0 +1,32 @@
+/*
+ * ============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.simulators.xnf.config
+
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+internal data class SimulatorConfiguration(
+ val vesHost: String,
+ val vesPort: Int,
+ val security: SecurityConfiguration,
+ val messagesAmount: Long)
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/factory.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/factory.kt
new file mode 100644
index 00000000..dce386b1
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/factory.kt
@@ -0,0 +1,30 @@
+/*
+ * ============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.simulators.xnf
+
+import org.onap.dcae.collectors.veshv.simulators.xnf.api.MessageGenerator
+import org.onap.dcae.collectors.veshv.simulators.xnf.impl.MessageGeneratorImpl
+import org.onap.dcae.collectors.veshv.simulators.xnf.impl.PayloadGenerator
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since June 2018
+ */
+fun createMessageGenerator(): MessageGenerator = MessageGeneratorImpl(PayloadGenerator())
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/HttpServer.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/HttpServer.kt
new file mode 100644
index 00000000..b67bc644
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/HttpServer.kt
@@ -0,0 +1,116 @@
+/*
+ * ============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.simulators.xnf.impl
+
+import arrow.effects.IO
+import org.onap.dcae.collectors.veshv.domain.WireFrame
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.MessageParameters
+import org.onap.dcae.collectors.veshv.utils.logging.Logger
+import ratpack.exec.Promise
+import ratpack.handling.Chain
+import ratpack.handling.Context
+import ratpack.server.RatpackServer
+import ratpack.server.ServerConfig
+import reactor.core.publisher.Flux
+import reactor.core.scheduler.Schedulers
+import javax.json.Json
+import javax.json.JsonObject
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+internal class HttpServer(private val vesClient: XnfSimulator) {
+
+ fun start(port: Int = DEFAULT_PORT): IO<RatpackServer> = IO {
+ RatpackServer.start { server ->
+ server.serverConfig(ServerConfig.embedded().port(port))
+ .handlers(this::configureHandlers)
+ }
+ }
+
+
+ private fun configureHandlers(chain: Chain) {
+ chain
+ .post("simulator/sync") { ctx ->
+ createMessageFlux(ctx)
+ .map { vesClient.sendIo(it) }
+ .map { it.unsafeRunSync() }
+ .onError { handleException(it, ctx) }
+ .then { sendAcceptedResponse(ctx) }
+ }
+ .post("simulator/async") { ctx ->
+ createMessageFlux(ctx)
+ .map { vesClient.sendRx(it) }
+ .map { it.subscribeOn(Schedulers.elastic()).subscribe() }
+ .onError { handleException(it, ctx) }
+ .then { sendAcceptedResponse(ctx) }
+ }
+ }
+
+ private fun createMessageFlux(ctx: Context): Promise<Flux<WireFrame>> {
+ return ctx.request.body
+ .map { Json.createReader(it.inputStream).readObject() }
+ .map { extractMessageParameters(it) }
+ .map { MessageGeneratorImpl.INSTANCE.createMessageFlux(it) }
+ }
+
+ private fun sendAcceptedResponse(ctx: Context) {
+ ctx.response
+ .status(STATUS_OK)
+ .send(CONTENT_TYPE_APPLICATION_JSON, Json.createObjectBuilder()
+ .add("response", "Request accepted")
+ .build()
+ .toString())
+ }
+
+ private fun handleException(t: Throwable, ctx: Context) {
+ logger.warn("Failed to process the request - ${t.localizedMessage}")
+ logger.debug("Exception thrown when processing the request", t)
+ ctx.response
+ .status(STATUS_BAD_REQUEST)
+ .send(CONTENT_TYPE_APPLICATION_JSON, Json.createObjectBuilder()
+ .add("response", "Request was not accepted")
+ .add("exception", t.localizedMessage)
+ .build()
+ .toString())
+ }
+
+ private fun extractMessageParameters(request: JsonObject): MessageParameters =
+ try {
+ val commonEventHeader = MessageGeneratorImpl.INSTANCE
+ .parseCommonHeader(request.getJsonObject("commonEventHeader"))
+ val messagesAmount = request.getJsonNumber("messagesAmount").longValue()
+ MessageParameters(commonEventHeader, messagesAmount)
+ } catch (e: Exception) {
+ throw ValidationException("Validating request body failed", e)
+ }
+
+
+ companion object {
+ private val logger = Logger(HttpServer::class)
+ const val DEFAULT_PORT = 5000
+ const val STATUS_OK = 200
+ const val STATUS_BAD_REQUEST = 400
+ const val CONTENT_TYPE_APPLICATION_JSON = "application/json"
+ }
+}
+
+internal class ValidationException(message: String?, cause: Exception) : Exception(message, cause)
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageGeneratorImpl.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageGeneratorImpl.kt
new file mode 100644
index 00000000..0d28bad0
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageGeneratorImpl.kt
@@ -0,0 +1,79 @@
+/*
+ * ============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.simulators.xnf.impl
+
+import com.google.protobuf.ByteString
+import org.onap.dcae.collectors.veshv.domain.WireFrame
+import org.onap.dcae.collectors.veshv.simulators.xnf.api.MessageGenerator
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.MessageParameters
+import org.onap.ves.VesEventV5.VesEvent
+import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Mono
+import javax.json.JsonObject
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+internal class MessageGeneratorImpl(private val payloadGenerator: PayloadGenerator) : MessageGenerator {
+
+ override fun createMessageFlux(messageParameters: MessageParameters): Flux<WireFrame> =
+ Mono.fromCallable { createMessage(messageParameters.commonEventHeader) }.let {
+ if (messageParameters.amount < 0)
+ it.repeat()
+ else
+ it.repeat(messageParameters.amount)
+ }
+
+ fun parseCommonHeader(json: JsonObject): CommonEventHeader = CommonEventHeader.newBuilder()
+ .setVersion(json.getString("version"))
+ .setDomain(CommonEventHeader.Domain.forNumber(json.getInt("domain")))
+ .setSequence(json.getInt("sequence"))
+ .setPriority(CommonEventHeader.Priority.forNumber(json.getInt("priority")))
+ .setEventId(json.getString("eventId"))
+ .setEventName(json.getString("eventName"))
+ .setEventType(json.getString("eventType"))
+ .setStartEpochMicrosec(json.getJsonNumber("startEpochMicrosec").longValue())
+ .setLastEpochMicrosec(json.getJsonNumber("lastEpochMicrosec").longValue())
+ .setNfNamingCode(json.getString("nfNamingCode"))
+ .setNfcNamingCode(json.getString("nfcNamingCode"))
+ .setReportingEntityId(json.getString("reportingEntityId"))
+ .setReportingEntityName(ByteString.copyFromUtf8(json.getString("reportingEntityName")))
+ .setSourceId(ByteString.copyFromUtf8(json.getString("sourceId")))
+ .setSourceName(json.getString("sourceName"))
+ .build()
+
+
+ private fun createMessage(commonHeader: CommonEventHeader): WireFrame =
+ WireFrame(vesMessageBytes(commonHeader))
+
+
+ private fun vesMessageBytes(commonHeader: CommonEventHeader): ByteArray =
+ VesEvent.newBuilder()
+ .setCommonEventHeader(commonHeader)
+ .setHvRanMeasFields(payloadGenerator.generatePayload().toByteString())
+ .build()
+ .toByteArray()
+
+ companion object {
+ val INSTANCE = MessageGeneratorImpl(PayloadGenerator())
+ }
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGenerator.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGenerator.kt
new file mode 100644
index 00000000..c8b97639
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGenerator.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.simulators.xnf.impl
+
+import org.onap.ves.HVRanMeasFieldsV5.HVRanMeasFields.HVRanMeasPayload
+import org.onap.ves.HVRanMeasFieldsV5.HVRanMeasFields.HVRanMeasPayload.PMObject
+import org.onap.ves.HVRanMeasFieldsV5.HVRanMeasFields.HVRanMeasPayload.PMObject.HVRanMeas
+import java.util.*
+
+internal class PayloadGenerator {
+
+ private val randomGenerator = Random()
+
+ fun generatePayload(numOfCountPerMeas: Long = 2, numOfMeasPerObject: Int = 2): HVRanMeasPayload {
+ val pmObject = generatePmObject(numOfCountPerMeas, numOfMeasPerObject)
+ return HVRanMeasPayload.newBuilder()
+ .addPmObject(pmObject)
+ .build()
+ }
+
+ private fun generatePmObject(numOfCountPerMeas: Long, numOfMeasPerObject: Int): PMObject {
+ val hvRanMeasList = MutableList(numOfMeasPerObject) { generateHvRanMeas(numOfCountPerMeas) }
+ val finalUriName = URI_BASE_NAME + randomGenerator.nextInt(UPPER_URI_NUMBER_BOUND)
+ return HVRanMeasPayload.PMObject.newBuilder()
+ .setUri(finalUriName)
+ .addAllHvRanMeas(hvRanMeasList.asIterable())
+ .build()
+ }
+
+ private fun generateHvRanMeas(numOfCountPerMeas: Long): HVRanMeas {
+ return HVRanMeasPayload.PMObject.HVRanMeas.newBuilder()
+ .setMeasurementId(randomGenerator.nextInt())
+ .addAllCounterSubid(Iterable { randomGenerator.ints(numOfCountPerMeas).iterator() })
+ .addAllCounterValue(Iterable { randomGenerator.longs(numOfCountPerMeas).iterator() })
+ .setSuspectFlagIncomplete(false)
+ .setSuspectFlagOutOfSync(false)
+ .build()
+ }
+
+ companion object {
+ private const val URI_BASE_NAME = "sample/uri"
+ private const val UPPER_URI_NUMBER_BOUND = 10_000
+ }
+
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/XnfSimulator.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/XnfSimulator.kt
new file mode 100644
index 00000000..6487888e
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/XnfSimulator.kt
@@ -0,0 +1,121 @@
+/*
+ * ============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.simulators.xnf.impl
+
+import arrow.effects.IO
+import io.netty.buffer.Unpooled
+import io.netty.handler.ssl.ClientAuth
+import io.netty.handler.ssl.SslContext
+import io.netty.handler.ssl.SslContextBuilder
+import io.netty.handler.ssl.SslProvider
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.domain.WireFrame
+import org.onap.dcae.collectors.veshv.domain.WireFrameEncoder
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.SimulatorConfiguration
+import org.onap.dcae.collectors.veshv.utils.logging.Logger
+import org.reactivestreams.Publisher
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Mono
+import reactor.core.publisher.ReplayProcessor
+import reactor.ipc.netty.NettyOutbound
+import reactor.ipc.netty.tcp.TcpClient
+
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+internal class XnfSimulator(private val configuration: SimulatorConfiguration) {
+
+ private val client: TcpClient = TcpClient.builder()
+ .options { opts ->
+ opts.host(configuration.vesHost)
+ .port(configuration.vesPort)
+ .sslContext(createSslContext(configuration.security))
+ }
+ .build()
+
+ fun sendIo(messages: Flux<WireFrame>) = IO<Unit> {
+ sendRx(messages).block()
+ }
+
+ fun sendRx(messages: Flux<WireFrame>): Mono<Void> {
+ val complete = ReplayProcessor.create<Void>(1)
+ client
+ .newHandler { _, output -> handler(complete, messages, output) }
+ .doOnError {
+ logger.info("Failed to connect to VesHvCollector on " +
+ "${configuration.vesHost}:${configuration.vesPort}")
+ }
+ .subscribe {
+ logger.info("Connected to VesHvCollector on " +
+ "${configuration.vesHost}:${configuration.vesPort}")
+ }
+ return complete.then()
+ }
+
+ private fun handler(complete: ReplayProcessor<Void>, messages: Flux<WireFrame>, nettyOutbound: NettyOutbound):
+ Publisher<Void> {
+ val encoder = WireFrameEncoder(nettyOutbound.alloc())
+ val context = nettyOutbound.context()
+
+ context.onClose {
+ logger.info { "Connection to ${context.address()} has been closed" }
+ }
+
+ // TODO: Close channel after all messages have been sent
+ // The code bellow doesn't work because it closes the channel earlier and not all are consumed...
+// complete.subscribe {
+// context.channel().disconnect().addListener {
+// if (it.isSuccess)
+// logger.info { "Connection closed" }
+// else
+// logger.warn("Failed to close the connection", it.cause())
+// }
+// }
+
+ val frames = messages
+ .map(encoder::encode)
+ .window(MAX_BATCH_SIZE)
+
+ return nettyOutbound
+ .options { it.flushOnBoundary() }
+ .sendGroups(frames)
+ .send(Mono.just(Unpooled.EMPTY_BUFFER))
+ .then {
+ logger.info("Messages have been sent")
+ complete.onComplete()
+ }
+ .then()
+ }
+
+ private fun createSslContext(config: SecurityConfiguration): SslContext =
+ SslContextBuilder.forClient()
+ .keyManager(config.cert.toFile(), config.privateKey.toFile())
+ .trustManager(config.trustedCert.toFile())
+ .sslProvider(SslProvider.OPENSSL)
+ .clientAuth(ClientAuth.REQUIRE)
+ .build()
+
+ companion object {
+ private const val MAX_BATCH_SIZE = 128
+ private val logger = Logger(XnfSimulator::class)
+ }
+}
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt
new file mode 100644
index 00000000..facf611a
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt
@@ -0,0 +1,53 @@
+/*
+ * ============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.simulators.xnf
+
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider
+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
+import org.onap.dcae.collectors.veshv.utils.arrow.unsafeRunEitherSync
+import org.onap.dcae.collectors.veshv.utils.arrow.void
+import org.onap.dcae.collectors.veshv.utils.commandline.handleWrongArgumentErrorCurried
+import org.onap.dcae.collectors.veshv.utils.logging.Logger
+
+private const val PACKAGE_NAME = "org.onap.dcae.collectors.veshv.simulators.xnf"
+private val logger = Logger(PACKAGE_NAME)
+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)
+ .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME))
+ .map(::XnfSimulator)
+ .map(::HttpServer)
+ .map { it.start().void() }
+ .unsafeRunEitherSync(
+ { ex ->
+ logger.error("Failed to start a server", ex)
+ ExitFailure(1)
+ },
+ {
+ logger.info("Started xNF Simulator API server")
+ }
+ )
diff --git a/hv-collector-xnf-simulator/src/main/resources/logback.xml b/hv-collector-xnf-simulator/src/main/resources/logback.xml
new file mode 100644
index 00000000..809f62d4
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/main/resources/logback.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <property name="LOG_FILE"
+ value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}ves-hv.log}"/>
+ <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} %-5level [%-40.40logger{10}] - %msg%n"/>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>
+ %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} %highlight(%-5level) [%-40.40logger{10}] - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <appender name="ROLLING-FILE"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <encoder>
+ <pattern>${FILE_LOG_PATTERN}</pattern>
+ </encoder>
+ <file>${LOG_FILE}</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
+ </rollingPolicy>
+ </appender>
+
+ <logger name="org.onap.dcae.collectors.veshv" level="DEBUG"/>
+
+ <root level="INFO">
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="ROLLING-FILE"/>
+ </root>
+</configuration> \ No newline at end of file
diff --git a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt
new file mode 100644
index 00000000..f2f92fff
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt
@@ -0,0 +1,126 @@
+/*
+ * ============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.main.config
+
+import arrow.core.identity
+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.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider.*
+import org.onap.dcae.collectors.veshv.simulators.xnf.config.SimulatorConfiguration
+import java.nio.file.Paths
+
+
+object ArgConfigurationProviderTest : Spek({
+ lateinit var cut: ArgConfigurationProvider
+ val messagesAmount = 3L
+ val vesHost = "localhosting"
+ 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()
+ }
+
+ fun parse(vararg cmdLine: String): SimulatorConfiguration =
+ cut.parse(cmdLine).fold(
+ {throw AssertionError("Parsing result should be present")},
+ ::identity
+ )
+
+ describe("parsing arguments") {
+ lateinit var result: SimulatorConfiguration
+
+ given("all parameters are present in the long form") {
+
+ beforeEachTest {
+ result = parse("--ves-port", "6969",
+ "--ves-host", vesHost,
+ "--messages", messagesAmount.toString(),
+ "--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 config url") {
+ assertThat(result.messagesAmount).isEqualTo(messagesAmount)
+ }
+
+ it("should set proper security configuration") {
+ assertThat(result.security).isEqualTo(
+ SecurityConfiguration(pk, cert, trustCert)
+ )
+ }
+ }
+
+ given("some parameters are present in the short form") {
+
+ beforeEachTest {
+ result = parse("-h", "ves-hv", "--ves-port", "666", "-m", messagesAmount.toString())
+ }
+
+ it("should set proper port") {
+ assertThat(result.vesPort).isEqualTo(666)
+ }
+
+ it("should set proper messages amount") {
+ assertThat(result.messagesAmount).isEqualTo(messagesAmount)
+ }
+ }
+
+ given("all optional parameters are absent") {
+
+ beforeEachTest {
+ result = parse("-h", "ves-hv", "-p", "666")
+ }
+
+ it("should set default messages amount") {
+ assertThat(result.messagesAmount).isEqualTo(DefaultValues.MESSAGES_AMOUNT)
+ }
+
+ on("security config") {
+ val securityConfiguration = result.security
+
+ it("should set default trust cert file") {
+ assertThat(securityConfiguration.trustedCert.toString()).isEqualTo(DefaultValues.TRUST_CERT_FILE)
+ }
+
+ it("should set default server cert file") {
+ assertThat(securityConfiguration.cert.toString()).isEqualTo(DefaultValues.CERT_FILE)
+ }
+
+ it("should set default private key file") {
+ assertThat(securityConfiguration.privateKey.toString()).isEqualTo(DefaultValues.PRIVATE_KEY_FILE)
+ }
+ }
+ }
+ }
+})
diff --git a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageFactoryTest.kt b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageFactoryTest.kt
new file mode 100644
index 00000000..6f8a95a4
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/MessageFactoryTest.kt
@@ -0,0 +1,83 @@
+/*
+ * ============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.simulators.xnf.impl
+
+import com.google.protobuf.ByteString
+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.onap.dcae.collectors.veshv.simulators.xnf.config.MessageParameters
+import org.onap.ves.VesEventV5
+import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader.Domain.HVRANMEAS
+import org.onap.ves.VesEventV5.VesEvent.CommonEventHeader.Priority.MEDIUM
+import reactor.test.test
+
+const val SAMPLE_START_EPOCH: Long = 120034455
+const val SAMPLE_LAST_EPOCH: Long = 120034455
+
+/**
+ * @author Jakub Dudycz <jakub.dudycz@nokia.com>
+ * @since June 2018
+ */
+object MessageFactoryTest : Spek({
+ describe("message factory") {
+
+ val factory = MessageGeneratorImpl.INSTANCE
+
+ given("only common header") {
+ it("should return infinite flux") {
+ val limit = 1000L
+ factory.createMessageFlux(getSampleMessageParameters()).take(limit).test()
+ .expectNextCount(limit)
+ .verifyComplete()
+ }
+ }
+ given("common header and messages amount") {
+ it("should return message flux of specified size") {
+ factory.createMessageFlux((getSampleMessageParameters(5))).test()
+ .expectNextCount(5)
+ .verifyComplete()
+ }
+ }
+ }
+})
+
+fun getSampleMessageParameters(amount: Long = -1): MessageParameters{
+ val commonHeader = VesEventV5.VesEvent.CommonEventHeader.newBuilder()
+ .setVersion("sample-version")
+ .setDomain(HVRANMEAS)
+ .setSequence(1)
+ .setPriority(MEDIUM)
+ .setEventId("sample-event-id")
+ .setEventName("sample-event-name")
+ .setEventType("sample-event-type")
+ .setStartEpochMicrosec(SAMPLE_START_EPOCH)
+ .setLastEpochMicrosec(SAMPLE_LAST_EPOCH)
+ .setNfNamingCode("sample-nf-naming-code")
+ .setNfcNamingCode("sample-nfc-naming-code")
+ .setReportingEntityId("sample-reporting-entity-id")
+ .setReportingEntityName(ByteString.copyFromUtf8("sample-reporting-entity-name"))
+ .setSourceId(ByteString.copyFromUtf8("sample-source-id"))
+ .setSourceName("sample-source-name")
+ .build()
+
+ return MessageParameters(commonHeader, amount)
+}
diff --git a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGeneratorTest.kt b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGeneratorTest.kt
new file mode 100644
index 00000000..73129a7f
--- /dev/null
+++ b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/PayloadGeneratorTest.kt
@@ -0,0 +1,74 @@
+/*
+ * ============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.simulators.xnf.impl
+
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+import org.assertj.core.api.Assertions.assertThat
+import org.jetbrains.spek.api.dsl.on
+
+private const val DEFAULT_MEASUREMENTS_NUMBER = 2
+private const val DEFAULT_COUNTERS_NUMBER = 2
+
+private val uriRegex = """sample/uri(\d+)""".toRegex()
+
+object PayloadGeneratorTest : Spek({
+
+ given("payload factory object") {
+ val payloadGenerator = PayloadGenerator()
+
+ on("two generated payloads") {
+ val generatedPayload0 = payloadGenerator.generatePayload()
+ val generatedPayload1 = payloadGenerator.generatePayload()
+ it("URIs should have different names") {
+ val matchResult0 = uriRegex.find(generatedPayload0.getPmObject(0).uri)!!.value
+ val matchResult1 = uriRegex.find(generatedPayload1.getPmObject(0).uri)!!.value
+ assertThat(matchResult0 != matchResult1).isTrue()
+ }
+ }
+
+ on("call with default parameters") {
+ val generatedPayload = payloadGenerator.generatePayload()
+ it("should contain default numbers of measurements") {
+ assertThat(generatedPayload.getPmObject(0).hvRanMeasCount).isEqualTo(DEFAULT_MEASUREMENTS_NUMBER)
+ }
+ it("should contain default numbers of counters in measurement") {
+ assertThat(generatedPayload.getPmObject(0).getHvRanMeas(0).counterSubidCount).isEqualTo(DEFAULT_COUNTERS_NUMBER)
+ }
+ }
+
+ on("call with specified parameters") {
+ val numOfCountPerMeas: Long = 5
+ val numOfMeasPerObject: Int = 10
+ val generatedPayload = payloadGenerator.generatePayload(numOfCountPerMeas, numOfMeasPerObject)
+ it("should contain specified number of measurements") {
+ assertThat(generatedPayload.getPmObject(0).hvRanMeasCount).isEqualTo(numOfMeasPerObject)
+ }
+ it("measurement should contain specified number of counters") {
+ assertThat(generatedPayload.getPmObject(0).hvRanMeasList
+ .filter { numOfCountPerMeas.toInt() == it.counterSubidCount }
+ .size)
+ .isEqualTo(numOfMeasPerObject)
+ }
+
+ }
+ }
+})