From 8d0066e435caa66fdd271d14025788299809ab14 Mon Sep 17 00:00:00 2001 From: Pawel Kadlubanski Date: Fri, 11 May 2018 14:35:43 +0200 Subject: Add pnf simulator Issue-ID: INT-458 Change-Id: I6fd6b58e5d302d83e4b4e1d1dfd59247a6df9700 Signed-off-by: Pawel Kadlubanski --- .../src/main/java/org/onap/pnfsimulator/Main.java | 37 +++++++++ .../org/onap/pnfsimulator/cli/SimulatorParams.java | 45 +++++++++++ .../pnfsimulator/cli/SimulatorParamsProvider.java | 41 ++++++++++ .../pnfsimulator/message/MessageConstants.java | 33 ++++++++ .../onap/pnfsimulator/message/MessageProvider.java | 88 ++++++++++++++++++++++ .../org/onap/pnfsimulator/simulator/Simulator.java | 45 +++++++++++ .../pnfsimulator/simulator/SimulatorFactory.java | 42 +++++++++++ .../simulator/client/HttpClientProvider.java | 56 ++++++++++++++ .../simulator/validation/ParamsValidator.java | 82 ++++++++++++++++++++ .../simulator/validation/ValidationException.java | 8 ++ .../pnfsimulator/src/main/resources/log4j2.xml | 19 +++++ 11 files changed, 496 insertions(+) create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParams.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/cli/SimulatorParamsProvider.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageConstants.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/Simulator.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorFactory.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientProvider.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ParamsValidator.java create mode 100644 test/mocks/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/validation/ValidationException.java create mode 100644 test/mocks/pnfsimulator/src/main/resources/log4j2.xml (limited to 'test/mocks/pnfsimulator/src/main') 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 000000000..7dfa68669 --- /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 000000000..64b3589ac --- /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 000000000..fcf5d79f6 --- /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 000000000..77b372721 --- /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 000000000..5e8e535f9 --- /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 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 000000000..75ce71e5e --- /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 000000000..c9bd8d7fe --- /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 000000000..a24889cb3 --- /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 000000000..a0fc110bd --- /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> paramValidators = ImmutableMap + .>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 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 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 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 000000000..9855a784e --- /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 000000000..250f41709 --- /dev/null +++ b/test/mocks/pnfsimulator/src/main/resources/log4j2.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + -- cgit 1.2.3-korg