Add pnf simulator
Issue-ID: INT-458
Change-Id: I6fd6b58e5d302d83e4b4e1d1dfd59247a6df9700
Signed-off-by: Pawel Kadlubanski <pawel.kadlubanski@nokia.com>
diff --git a/test/mocks/pnfsimulator/README.md b/test/mocks/pnfsimulator/README.md
new file mode 100644
index 0000000..5b9871a
--- /dev/null
+++ b/test/mocks/pnfsimulator/README.md
@@ -0,0 +1,2 @@
+# pnf-simulator
+Generate VES event related to PNF integration.
diff --git a/test/mocks/pnfsimulator/body.json b/test/mocks/pnfsimulator/body.json
new file mode 100644
index 0000000..e0de14a
--- /dev/null
+++ b/test/mocks/pnfsimulator/body.json
@@ -0,0 +1,18 @@
+{
+"testDuration": "10",
+"messageInterval": "1",
+"pnfSerialNumber": "val1",
+"pnfVendorName": "val2",
+"pnfOamIpv4Address": "val3",
+"pnfOamIpv6Address": "val4",
+"pnfFamily": "val5",
+"pnfModelNumber": "val6",
+"pnfSoftwareVersion": "val7",
+"pnfType": "val8",
+"eventName": "val9",
+"nfNamingCode": "val10",
+"nfcNamingCode": "val11",
+"sourceName": "val12",
+"sourceId": "val13",
+"reportingEntityName": "val14"
+}
diff --git a/test/mocks/pnfsimulator/pom.xml b/test/mocks/pnfsimulator/pom.xml
new file mode 100644
index 0000000..4b39d75
--- /dev/null
+++ b/test/mocks/pnfsimulator/pom.xml
@@ -0,0 +1,154 @@
+<?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>
+
+ <parent>
+ <groupId>org.onap.oparent</groupId>
+ <artifactId>oparent</artifactId>
+ <version>0.1.1</version>
+ </parent>
+
+ <groupId>org.onap.pnfsimulator</groupId>
+ <artifactId>pnf-simulator</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>pnf-simulator</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ <simulator.main.class>org.onap.pnfsimulator.Main</simulator.main.class>
+ <dependency.directory.name>libs</dependency.directory.name>
+ <dependency.directory.location>${project.build.directory}/${dependency.directory.name}</dependency.directory.location>
+ <onap.nexus.dockerregistry.daily>nexus3.onap.org:10003</onap.nexus.dockerregistry.daily>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.11.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20180130</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.5.5</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>21.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>5.1.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.9.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.7</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ <showWarnings>true</showWarnings>
+ <showDeprecation>true</showDeprecation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-surefire-provider</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <detail>true</detail>
+ <printSummary>true</printSummary>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <configuration>
+ <outputDirectory>${dependency.directory.location}</outputDirectory>
+ <includeScope>runtime</includeScope>
+ <silent>true</silent>
+ </configuration>
+ <executions>
+ <execution>
+ <id>copy-external-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <configuration>
+ <skipDockerBuild>false</skipDockerBuild>
+ <imageName>
+ ${onap.nexus.dockerregistry.daily}/onap/${project.groupId}.${project.artifactId}
+ </imageName>
+ <cmd>java -cp ${dependency.directory.name}/*:${project.build.finalName}.jar ${simulator.main.class}
+ </cmd>
+ <resources>
+ <resource>
+ <targetPath>${dependency.directory.name}</targetPath>
+ <directory>${dependency.directory.location}</directory>
+ </resource>
+ <resource>
+ <targetPath>/</targetPath>
+ <directory>${project.build.directory}</directory>
+ <include>${project.build.finalName}.jar</include>
+ </resource>
+ </resources>
+ <imageTags>
+ <imageTag>${project.version}-SNAPSHOT-${maven.build.timestamp}Z</imageTag>
+ <imageTag>${project.version}</imageTag>
+ <imageTag>latest</imageTag>
+ </imageTags>
+ <serverId>${onap.nexus.dockerregistry.daily}</serverId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/test/mocks/pnfsimulator/simulator.sh b/test/mocks/pnfsimulator/simulator.sh
new file mode 100755
index 0000000..27384dd
--- /dev/null
+++ b/test/mocks/pnfsimulator/simulator.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+CONTAINER_NAME=pnf-simulator
+CONFIG_FILE_PATH=/config/body.json
+SIMULATOR_DOCKER_HUB=hub-name
+SIMULATOR_TAG=latest
+
+function main(){
+
+ COMMAND=${1:-"help"}
+
+ case $COMMAND in
+ "build")
+ build_image;;
+ "start")
+ start_simulator $2 $CONFIG_FILE_PATH $SIMULATOR_DOCKER_HUB/pnf-simulator:$SIMULATOR_TAG;;
+ "start-dev")
+ start_simulator $2 $CONFIG_FILE_PATH pnf-simulator:$SIMULATOR_TAG;;
+ "stop")
+ stop_simulator;;
+ "status")
+ print_status;;
+ "logs")
+ get_logs;;
+ "help")
+ print_help;;
+ *)
+ print_help;;
+ esac
+}
+
+function build_image(){
+ if [ -f pom.xml ]; then
+ mvn clean package
+ else
+ echo "pom.xml file not found"
+ exit 1
+ fi
+}
+
+function start_simulator(){
+
+ stop_and_remove_container || true
+
+ if [ $(docker run -d --name $CONTAINER_NAME -v $(pwd):/config -e VES_ADDRESS=$1 -e CONFIG_FILE_PATH=$2 $3) > /dev/null ]; then
+ echo "Simulator started"
+ else
+ echo "Failed to start simulator"
+ fi
+}
+
+function stop_and_remove_container(){
+ docker rm -f $CONTAINER_NAME 1> /dev/null
+}
+
+function stop_simulator(){
+ if [ $(docker kill $CONTAINER_NAME) > /dev/null ]; then
+ echo "Simulator stopped"
+ else
+ echo "Failed to stop simulator"
+ fi
+
+}
+
+function print_status(){
+cat << EndOfMessage
+
+Simulator container status:
+
+$(docker ps -a -f name=$CONTAINER_NAME)
+
+EndOfMessage
+}
+
+function print_help(){
+cat << EndOfMessage
+
+Available options:
+build - locally builds simulator image from existing code
+start <ves-url> - starts simulator using remote docker image and connects to given VES server
+start-dev <ves-url> - starts simulator using local docker image and connects to given VES server
+stop - stops simulator
+status - prints container status
+logs - prints logs
+help - prints this message
+
+Starting simulation:
+Use "./simulator.sh start". It will download required docker image from the internet and start simulator using body.json file
+
+To stop simulation use "./simulator.sh stop" command. To check simulator's status use "./simulator.sh status".
+If you want to change message parameters simply edit body.json file then run simulator again.
+
+FOR DEVELOPERS
+1. Build local simulator image using "./simulator.sh build"
+2. Run simulation with "./simulator.sh start-dev"
+
+If you change the source code you have to rebuild image with "./simulator.sh build" and run "./simulator.sh start-dev" again
+
+EndOfMessage
+}
+
+function get_logs(){
+ docker logs --tail all $CONTAINER_NAME
+}
+
+main $@
\ No newline at end of file
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java
new file mode 100644
index 0000000..7dfa686
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java
@@ -0,0 +1,37 @@
+package org.onap.pnfsimulator;
+
+import java.io.IOException;
+import org.apache.commons.cli.ParseException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.onap.pnfsimulator.cli.SimulatorParamsProvider;
+import org.onap.pnfsimulator.cli.SimulatorParams;
+import org.onap.pnfsimulator.message.MessageProvider;
+import org.onap.pnfsimulator.simulator.SimulatorFactory;
+import org.onap.pnfsimulator.simulator.validation.ParamsValidator;
+import org.onap.pnfsimulator.simulator.validation.ValidationException;
+
+public class Main {
+
+ private static Logger logger = LogManager.getLogger(Main.class);
+ private static SimulatorFactory simulatorFactory =
+ new SimulatorFactory(MessageProvider.getInstance(), ParamsValidator.getInstance());
+
+ public static void main(String[] args) {
+
+ try {
+
+ SimulatorParams params = new SimulatorParamsProvider().parse(args);
+ simulatorFactory
+ .create(params.getVesAddress(), params.getConfigFilePath())
+ .start();
+
+ } catch (IOException e) {
+ logger.error("Invalid config file format", e);
+ } catch (ParseException e) {
+ logger.error("Invalid cli params", e);
+ } catch (ValidationException e){
+ logger.error("Missing some mandatory params:", e);
+ }
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParams.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParams.java
new file mode 100644
index 0000000..64b3589
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParams.java
@@ -0,0 +1,45 @@
+package org.onap.pnfsimulator.cli;
+
+import java.util.Objects;
+
+public class SimulatorParams {
+
+ private String vesAddress;
+ private String configFilePath;
+
+ public SimulatorParams(String vesAddress, String configFilePath) {
+ this.vesAddress = vesAddress;
+ this.configFilePath = configFilePath;
+ }
+
+ public String getVesAddress() {
+ return vesAddress;
+ }
+
+ public String getConfigFilePath() {
+ return configFilePath;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("VES address=%s, Configuration file=%s", vesAddress, configFilePath);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SimulatorParams)) {
+ return false;
+ }
+ SimulatorParams params = (SimulatorParams) o;
+ return Objects.equals(vesAddress, params.vesAddress) &&
+ Objects.equals(configFilePath, params.configFilePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(vesAddress, configFilePath);
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParamsProvider.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParamsProvider.java
new file mode 100644
index 0000000..fcf5d79
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParamsProvider.java
@@ -0,0 +1,41 @@
+package org.onap.pnfsimulator.cli;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+public class SimulatorParamsProvider {
+
+ private static final String CLI_VAR_VES_ADDRESS = "address";
+ private static final String CLI_VAR_CONFIG_FILE_PATH = "config";
+ private static final String ENV_VAR_VES_ADDRESS = "VES_ADDRESS";
+ private static final String ENV_VAR_CONFIG_FILE_PATH = "CONFIG_FILE_PATH";
+
+ private Options options;
+ private CommandLineParser parser;
+
+ public SimulatorParamsProvider() {
+ createOptions();
+ parser = new DefaultParser();
+ }
+
+ public SimulatorParams parse(String[] arg) throws ParseException {
+ CommandLine line = parser.parse(options, arg);
+ return new SimulatorParams(
+ line.getOptionValue(CLI_VAR_VES_ADDRESS, System.getenv().get(ENV_VAR_VES_ADDRESS)),
+ line.getOptionValue(CLI_VAR_CONFIG_FILE_PATH, System.getenv().get(ENV_VAR_CONFIG_FILE_PATH)));
+ }
+
+ private void createOptions() {
+ options = new Options();
+
+ Option vesCollectorUlrOpt = new Option(CLI_VAR_VES_ADDRESS, true, "VES collector URL");
+ options.addOption(vesCollectorUlrOpt);
+
+ Option simulatorConfigFilePathOpt = new Option(CLI_VAR_CONFIG_FILE_PATH, true, "Simulator configuration file location.");
+ options.addOption(simulatorConfigFilePathOpt);
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageConstants.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageConstants.java
new file mode 100644
index 0000000..77b3727
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageConstants.java
@@ -0,0 +1,33 @@
+package org.onap.pnfsimulator.message;
+
+public final class MessageConstants {
+
+ public static final String DOMAIN = "domain";
+ public static final String EVENT_ID = "eventId";
+ public static final String EVENT_TYPE = "eventType";
+ public static final String LAST_EPOCH_MICROSEC = "lastEpochMicrosec";
+ public static final String PRIORITY = "priority";
+ public static final String SEQUENCE = "sequence";
+ public static final String START_EPOCH_MICROSEC = "startEpochMicrosec";
+ public static final String INTERNAL_HEADER_FIELDS = "internalHeaderFields";
+ public static final String VERSION = "version";
+ public static final String OTHER_FIELDS_VERSION = "otherFieldsVersion";
+ public static final String PNF_LAST_SERVICE_DATE = "pnfLastServiceDate";
+ public static final String PNF_MANUFACTURE_DATE = "pnfManufactureDate";
+
+ // mandatory
+ public static final String PNF_OAM_IPV4_ADDRESS = "pnfOamIpv4Address";
+ public static final String PNF_OAM_IPV6_ADDRESS = "pnfOamIpv6Address";
+ public static final String PNF_SERIAL_NUMBER = "pnfSerialNumber";
+ public static final String PNF_VENDOR_NAME = "pnfVendorName";
+
+ public static final String PNF_PREFIX = "pnf";
+ public static final String COMMON_EVENT_HEADER = "commonEventHeader";
+ public static final String OTHER_FIELDS = "otherFields";
+ public static final String TEST_DURATION = "testDuration";
+ public static final String MESSAGE_INTERVAL = "messageInterval";
+
+ private MessageConstants() {
+ }
+
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java
new file mode 100644
index 0000000..5e8e535
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java
@@ -0,0 +1,88 @@
+package org.onap.pnfsimulator.message;
+
+import static org.onap.pnfsimulator.message.MessageConstants.COMMON_EVENT_HEADER;
+import static org.onap.pnfsimulator.message.MessageConstants.DOMAIN;
+import static org.onap.pnfsimulator.message.MessageConstants.EVENT_ID;
+import static org.onap.pnfsimulator.message.MessageConstants.EVENT_TYPE;
+import static org.onap.pnfsimulator.message.MessageConstants.INTERNAL_HEADER_FIELDS;
+import static org.onap.pnfsimulator.message.MessageConstants.LAST_EPOCH_MICROSEC;
+import static org.onap.pnfsimulator.message.MessageConstants.OTHER_FIELDS;
+import static org.onap.pnfsimulator.message.MessageConstants.OTHER_FIELDS_VERSION;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_LAST_SERVICE_DATE;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_MANUFACTURE_DATE;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_PREFIX;
+import static org.onap.pnfsimulator.message.MessageConstants.PRIORITY;
+import static org.onap.pnfsimulator.message.MessageConstants.SEQUENCE;
+import static org.onap.pnfsimulator.message.MessageConstants.START_EPOCH_MICROSEC;
+import static org.onap.pnfsimulator.message.MessageConstants.VERSION;
+
+import java.util.Map;
+import java.util.UUID;
+
+import com.google.common.base.Preconditions;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.json.JSONObject;
+
+public class MessageProvider {
+
+ private static MessageProvider instance;
+
+ public static MessageProvider getInstance() {
+ if (instance == null) {
+ instance = new MessageProvider();
+ }
+ return instance;
+ }
+
+ public JSONObject createMessage(JSONObject params) {
+
+ Preconditions.checkArgument(params != null, "Params object cannot be null");
+ Map<String, Object> paramsMap = params.toMap();
+ JSONObject root = new JSONObject();
+ JSONObject commonEventHeader = generateConstantCommonEventHeader();
+ JSONObject otherFields = generateConstantOtherFields();
+
+ paramsMap.forEach((key, value) -> {
+
+ if (key.startsWith(PNF_PREFIX)) {
+ otherFields.put(key, value);
+ } else {
+ commonEventHeader.put(key, value);
+ }
+ });
+
+ root.put(COMMON_EVENT_HEADER, commonEventHeader);
+ root.put(OTHER_FIELDS, otherFields);
+ return root;
+ }
+
+ private JSONObject generateConstantCommonEventHeader() {
+
+ JSONObject commonEventHeader = new JSONObject();
+ long timestamp = System.currentTimeMillis();
+
+ commonEventHeader.put(DOMAIN, "other");
+ commonEventHeader.put(EVENT_ID, UUID.randomUUID() + "-reg");
+ commonEventHeader.put(EVENT_TYPE, "pnfRegistration");
+ commonEventHeader.put(LAST_EPOCH_MICROSEC, timestamp);
+ commonEventHeader.put(PRIORITY, "Normal");
+ commonEventHeader.put(SEQUENCE, 0);
+ commonEventHeader.put(START_EPOCH_MICROSEC, timestamp);
+ commonEventHeader.put(INTERNAL_HEADER_FIELDS, new JSONObject());
+ commonEventHeader.put(VERSION, 3);
+
+ return commonEventHeader;
+ }
+
+ private JSONObject generateConstantOtherFields() {
+
+ JSONObject otherFields = new JSONObject();
+
+ otherFields.put(OTHER_FIELDS_VERSION, 1);
+ otherFields.put(PNF_LAST_SERVICE_DATE, System.currentTimeMillis());
+ otherFields.put(PNF_MANUFACTURE_DATE, System.currentTimeMillis());
+
+ return otherFields;
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/Simulator.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/Simulator.java
new file mode 100644
index 0000000..75ce71e
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/Simulator.java
@@ -0,0 +1,45 @@
+package org.onap.pnfsimulator.simulator;
+
+import java.time.Duration;
+import java.time.Instant;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.json.JSONObject;
+import org.onap.pnfsimulator.simulator.client.HttpClientProvider;
+
+public class Simulator {
+
+ private static final Logger logger = LogManager.getLogger(HttpClientProvider.class);
+ private HttpClientProvider clientProvider;
+ private JSONObject messageBody;
+ private Duration duration;
+ private Duration interval;
+
+ public Simulator(String vesServerUrl, JSONObject messageBody, Duration duration, Duration interval) {
+ this.messageBody = messageBody;
+ this.duration = duration;
+ this.interval = interval;
+ this.clientProvider = new HttpClientProvider(vesServerUrl);
+ }
+
+ public void start() {
+ logger.info("SIMULATOR STARTED - DURATION: {}s, INTERVAL: {}s", duration.getSeconds(), interval.getSeconds());
+
+ Instant endTime = Instant.now().plus(duration);
+ while (runningTimeNotExceeded(endTime)) {
+ try {
+ logger.info("MESSAGE TO BE SENT:\n{}", messageBody.toString(4));
+ clientProvider.sendMsg(messageBody.toString());
+ Thread.sleep(interval.toMillis());
+ } catch (InterruptedException e) {
+ logger.error("SIMULATOR INTERRUPTED");
+ break;
+ }
+ }
+ logger.info("SIMULATOR FINISHED");
+ }
+
+ private boolean runningTimeNotExceeded(Instant endTime) {
+ return Instant.now().isBefore(endTime);
+ }
+}
\ No newline at end of file
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorFactory.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorFactory.java
new file mode 100644
index 0000000..c9bd8d7
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorFactory.java
@@ -0,0 +1,42 @@
+package org.onap.pnfsimulator.simulator;
+
+import static org.onap.pnfsimulator.message.MessageConstants.MESSAGE_INTERVAL;
+import static org.onap.pnfsimulator.message.MessageConstants.TEST_DURATION;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.json.JSONObject;
+import org.onap.pnfsimulator.message.MessageProvider;
+import org.onap.pnfsimulator.simulator.validation.ParamsValidator;
+import org.onap.pnfsimulator.simulator.validation.ValidationException;
+
+public class SimulatorFactory {
+
+ private MessageProvider messageProvider;
+ private ParamsValidator paramsValidator;
+
+ public SimulatorFactory(MessageProvider messageProvider, ParamsValidator paramsValidator) {
+ this.messageProvider = messageProvider;
+ this.paramsValidator = paramsValidator;
+ }
+
+ public Simulator create(String vesServerUrl, String configFilePath) throws IOException, ValidationException {
+
+ String configJson = FileUtils.readFileToString(new File(configFilePath), StandardCharsets.UTF_8);
+ JSONObject configObject = new JSONObject(configJson);
+
+ paramsValidator.validate(configObject);
+ Duration duration = Duration.ofSeconds(parseJsonField(configObject, TEST_DURATION));
+ Duration interval = Duration.ofSeconds(parseJsonField(configObject, MESSAGE_INTERVAL));
+ JSONObject messageBody = messageProvider.createMessage(configObject);
+ return new Simulator(vesServerUrl, messageBody, duration, interval);
+ }
+
+ private int parseJsonField(JSONObject json, String fieldName) {
+ return Integer.parseInt((String) json.remove(fieldName));
+ }
+}
\ No newline at end of file
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientProvider.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientProvider.java
new file mode 100644
index 0000000..a24889c
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientProvider.java
@@ -0,0 +1,56 @@
+package org.onap.pnfsimulator.simulator.client;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class HttpClientProvider {
+
+ private static final Logger logger = LogManager.getLogger(HttpClientProvider.class);
+ private static final String CONTENT_TYPE = "Content-Type";
+ private static final String APPLICATION_JSON = "application/json";
+
+ private HttpClient client;
+ private String url;
+
+ public HttpClientProvider(String url) {
+
+ RequestConfig config = RequestConfig.custom()
+ .setConnectTimeout(1000)
+ .setConnectionRequestTimeout(1000)
+ .setSocketTimeout(1000)
+ .build();
+
+ this.client = HttpClientBuilder
+ .create()
+ .setDefaultRequestConfig(config)
+ .build();
+
+ this.url = url;
+ }
+
+ public void sendMsg(String content) {
+ try {
+ HttpPost request = createRequest(content);
+ HttpResponse response = client.execute(request);
+ logger.info("MESSAGE SENT, VES RESPONSE CODE: {}", response.getStatusLine());
+ } catch (IOException e) {
+ logger.info("ERROR SENDING MESSAGE TO VES: {}", e.getMessage());
+ }
+ }
+
+ private HttpPost createRequest(String content) throws UnsupportedEncodingException {
+ StringEntity stringEntity = new StringEntity(content);
+ HttpPost request = new HttpPost(url);
+ request.addHeader(CONTENT_TYPE, APPLICATION_JSON);
+ request.setEntity(stringEntity);
+ return request;
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ParamsValidator.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ParamsValidator.java
new file mode 100644
index 0000000..a0fc110
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ParamsValidator.java
@@ -0,0 +1,82 @@
+package org.onap.pnfsimulator.simulator.validation;
+
+import static org.onap.pnfsimulator.message.MessageConstants.MESSAGE_INTERVAL;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_OAM_IPV4_ADDRESS;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_OAM_IPV6_ADDRESS;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_SERIAL_NUMBER;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_VENDOR_NAME;
+import static org.onap.pnfsimulator.message.MessageConstants.TEST_DURATION;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiPredicate;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONObject;
+
+
+public class ParamsValidator {
+
+ private final static String MISSING_PARAMS_ERROR = "Some mandatory params are missing";
+ private static ParamsValidator instance;
+
+
+ public static ParamsValidator getInstance() {
+ if (instance == null) {
+ instance = new ParamsValidator();
+ }
+ return instance;
+ }
+
+ public void validate(JSONObject params) throws ValidationException {
+ ImmutableMap<String, BiPredicate<JSONObject, String>> paramValidators = ImmutableMap
+ .<String, BiPredicate<JSONObject, String>>builder()
+ .put(TEST_DURATION, this::isNotNumeric)
+ .put(MESSAGE_INTERVAL, this::isNotNumeric)
+ .put(PNF_SERIAL_NUMBER, this::nullOrEmpty)
+ .put(PNF_VENDOR_NAME, this::nullOrEmpty)
+ .put(PNF_OAM_IPV4_ADDRESS, this::nullOrEmpty)
+ .put(PNF_OAM_IPV6_ADDRESS, this::nullOrEmpty)
+ .build();
+
+ List<String> missingParams = new ArrayList<>();
+
+ paramValidators.forEach((param, validator) -> {
+ if (validator.test(params, param)) {
+ missingParams.add(param);
+ }
+ });
+
+ clearIPError(missingParams);
+ if (!missingParams.isEmpty()) {
+ throw new ValidationException(constructMessage(missingParams));
+ }
+ }
+
+ private String constructMessage(List<String> missingParams) {
+ StringBuilder msg = new StringBuilder(MISSING_PARAMS_ERROR);
+
+ missingParams.forEach(param -> {
+ msg.append('\n');
+ msg.append(param);
+ });
+
+ return msg.toString();
+ }
+
+ private boolean isNotNumeric(JSONObject params, String param) {
+ return nullOrEmpty(params, param) || !StringUtils.isNumeric(params.getString(param));
+ }
+
+ private boolean nullOrEmpty(JSONObject params, String param) {
+ return !params.has(param) || params.getString(param).isEmpty();
+ }
+
+ private void clearIPError(List<String> missingParams) {
+ // if only one IP is missing clear the error
+ if (!(missingParams.contains(PNF_OAM_IPV4_ADDRESS) && missingParams.contains(PNF_OAM_IPV6_ADDRESS))) {
+ missingParams.remove(PNF_OAM_IPV4_ADDRESS);
+ missingParams.remove(PNF_OAM_IPV6_ADDRESS);
+ }
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ValidationException.java b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ValidationException.java
new file mode 100644
index 0000000..9855a78
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ValidationException.java
@@ -0,0 +1,8 @@
+package org.onap.pnfsimulator.simulator.validation;
+
+public class ValidationException extends Exception {
+
+ public ValidationException(String message) {
+ super(message);
+ }
+}
diff --git a/test/mocks/pnfsimulator/src/main/resources/log4j2.xml b/test/mocks/pnfsimulator/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..250f417
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/main/resources/log4j2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+ <Properties>
+ <Property name="log4j.logLevel" value="info"/>
+ </Properties>
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{ISO8601} +%r [%t] %-5p %c %x - %m%n"/>
+ </Console>
+ <Console name="ColorConsole" target="SYSTEM_OUT">
+ <PatternLayout pattern="%style{%d{ISO8601} +%r}{yellow} %highlight{%-5level}{STYLE=Logback} %style{[%t]}{yellow} %style{%c{1.}}{BRIGHT} %message%n"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Root level="${sys:log4j.logLevel}">
+ <AppenderRef ref="ColorConsole"/>
+ </Root>
+ </Loggers>
+</Configuration>
diff --git a/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorParamsProviderTest.java b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorParamsProviderTest.java
new file mode 100644
index 0000000..96397ea
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorParamsProviderTest.java
@@ -0,0 +1,31 @@
+package org.onap.pnfsimulator;
+
+import org.apache.commons.cli.ParseException;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.pnfsimulator.cli.SimulatorParamsProvider;
+import org.onap.pnfsimulator.cli.SimulatorParams;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Java6Assertions.assertThat;
+
+public class SimulatorParamsProviderTest {
+
+ SimulatorParamsProvider parser;
+
+ @BeforeEach
+ public void setUp() {
+ parser = new SimulatorParamsProvider();
+ }
+
+ @Test
+ public void whenParserReceiveArgLisWithTwoCorrectParametersShouldReturnCorrectStructOfParams()
+ throws ParseException {
+ String[] arg = new String[]{
+ "-address", "http://localhost:808/eventListner/v5",
+ "-config", "config.json"};
+ SimulatorParams params = parser.parse(arg);
+ assertThat(params.getConfigFilePath()).isEqualToIgnoringCase("config.json");
+ assertThat(params.getVesAddress()).isEqualToIgnoringCase("http://localhost:808/eventListner/v5");
+ }
+}
\ No newline at end of file
diff --git a/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorTest.java b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorTest.java
new file mode 100644
index 0000000..ccbb728
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/SimulatorTest.java
@@ -0,0 +1,12 @@
+package org.onap.pnfsimulator;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SimulatorTest {
+
+ @Test
+ public void dummyTestToCheckEnvirometn() {
+ Assertions.assertThat(true).isTrue();
+ }
+}
\ No newline at end of file
diff --git a/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/message/MessageProviderTest.java b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/message/MessageProviderTest.java
new file mode 100644
index 0000000..3854057
--- /dev/null
+++ b/test/mocks/pnfsimulator/src/test/java/org/onap/pnfsimulator/message/MessageProviderTest.java
@@ -0,0 +1,110 @@
+package org.onap.pnfsimulator.message;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.onap.pnfsimulator.message.MessageConstants.COMMON_EVENT_HEADER;
+import static org.onap.pnfsimulator.message.MessageConstants.DOMAIN;
+import static org.onap.pnfsimulator.message.MessageConstants.EVENT_ID;
+import static org.onap.pnfsimulator.message.MessageConstants.EVENT_TYPE;
+import static org.onap.pnfsimulator.message.MessageConstants.INTERNAL_HEADER_FIELDS;
+import static org.onap.pnfsimulator.message.MessageConstants.LAST_EPOCH_MICROSEC;
+import static org.onap.pnfsimulator.message.MessageConstants.OTHER_FIELDS;
+import static org.onap.pnfsimulator.message.MessageConstants.OTHER_FIELDS_VERSION;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_LAST_SERVICE_DATE;
+import static org.onap.pnfsimulator.message.MessageConstants.PNF_MANUFACTURE_DATE;
+import static org.onap.pnfsimulator.message.MessageConstants.PRIORITY;
+import static org.onap.pnfsimulator.message.MessageConstants.SEQUENCE;
+import static org.onap.pnfsimulator.message.MessageConstants.START_EPOCH_MICROSEC;
+import static org.onap.pnfsimulator.message.MessageConstants.VERSION;
+
+import java.util.UUID;
+import org.json.JSONObject;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class MessageProviderTest {
+
+ private static final String testParamsJson =
+ "{\"key1\": \"val1\",\"key2\": \"val2\",\"pnfKey3\": \"pnfVal3\",\"key4\": \"val4\"}";
+
+ private static MessageProvider messageProvider;
+
+ @BeforeAll
+ public static void setup() {
+ messageProvider = MessageProvider.getInstance();
+ }
+
+ @Test
+ public void createMessage_should_throw_when_given_null_argument() {
+ assertThrows(IllegalArgumentException.class,
+ () -> messageProvider.createMessage(null),
+ "Params object cannot be null");
+ }
+
+ @Test
+ public void createMessage_should_create_constant_message_when_no_params_specified() {
+ JSONObject message = messageProvider.createMessage(new JSONObject());
+
+ JSONObject commonEventHeader = message.getJSONObject(COMMON_EVENT_HEADER);
+ JSONObject otherFields = message.getJSONObject(OTHER_FIELDS);
+
+ JSONObject expectedCommonEventHeader = generateConstantCommonEventHeader();
+ JSONObject expectedOtherFields = generateConstantOtherFields();
+
+ expectedCommonEventHeader
+ .toMap()
+ .forEach((key, val) -> assertTrue(commonEventHeader.has(key),
+ () -> String.format("Key %s is not present", key)));
+
+ expectedOtherFields
+ .toMap()
+ .forEach((key, val) -> assertTrue(otherFields.has(key),
+ () -> String.format("Key %s is not present", key)));
+ }
+
+
+ @Test
+ public void createMessage_should_add_specified_params_to_valid_subobjects() {
+ JSONObject params = new JSONObject(testParamsJson);
+ JSONObject message = messageProvider.createMessage(params);
+
+ JSONObject commonEventHeader = message.getJSONObject(COMMON_EVENT_HEADER);
+ JSONObject otherFields = message.getJSONObject(OTHER_FIELDS);
+
+ assertEquals("pnfVal3", otherFields.getString("pnfKey3"));
+ assertEquals("val1", commonEventHeader.getString("key1"));
+ assertEquals("val2", commonEventHeader.getString("key2"));
+ assertEquals("val4", commonEventHeader.getString("key4"));
+ }
+
+
+ private JSONObject generateConstantCommonEventHeader() {
+
+ JSONObject commonEventHeader = new JSONObject();
+ long timestamp = System.currentTimeMillis();
+
+ commonEventHeader.put(DOMAIN, "other");
+ commonEventHeader.put(EVENT_ID, UUID.randomUUID() + "-reg");
+ commonEventHeader.put(EVENT_TYPE, "pnfRegistration");
+ commonEventHeader.put(LAST_EPOCH_MICROSEC, timestamp);
+ commonEventHeader.put(PRIORITY, "Normal");
+ commonEventHeader.put(SEQUENCE, 0);
+ commonEventHeader.put(START_EPOCH_MICROSEC, timestamp);
+ commonEventHeader.put(INTERNAL_HEADER_FIELDS, new JSONObject());
+ commonEventHeader.put(VERSION, 3);
+
+ return commonEventHeader;
+ }
+
+ private JSONObject generateConstantOtherFields() {
+ JSONObject otherFields = new JSONObject();
+
+ otherFields.put(OTHER_FIELDS_VERSION, 1);
+ otherFields.put(PNF_LAST_SERVICE_DATE, 1517206400);
+ otherFields.put(PNF_MANUFACTURE_DATE, 1516406400);
+
+ return otherFields;
+ }
+
+}