aboutsummaryrefslogtreecommitdiffstats
path: root/models-sim/policy-models-simulators
diff options
context:
space:
mode:
Diffstat (limited to 'models-sim/policy-models-simulators')
-rw-r--r--models-sim/policy-models-simulators/pom.xml98
-rw-r--r--models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/ClassRestServerParameters.java48
-rw-r--r--models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/Main.java281
-rw-r--r--models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/SimulatorParameters.java82
-rw-r--r--models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/TopicServerParameters.java48
-rw-r--r--models-sim/policy-models-simulators/src/main/package/docker/Dockerfile59
-rw-r--r--models-sim/policy-models-simulators/src/main/package/docker/docker_build.sh67
-rw-r--r--models-sim/policy-models-simulators/src/main/package/docker/simulators.sh43
-rw-r--r--models-sim/policy-models-simulators/src/main/package/tarball/assembly.xml57
-rw-r--r--models-sim/policy-models-simulators/src/main/resources/logback.xml56
-rw-r--r--models-sim/policy-models-simulators/src/main/resources/ssl/policy-keystorebin0 -> 4447 bytes
-rw-r--r--models-sim/policy-models-simulators/src/main/resources/ssl/policy-truststorebin0 -> 124180 bytes
-rw-r--r--models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/ClassRestServerParametersTest.java48
-rw-r--r--models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/MainTest.java256
-rw-r--r--models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/SimulatorParametersTest.java47
-rw-r--r--models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/TopicServerParametersTest.java48
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/invalidSimParameters.json2
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/invalidTopicServer.json35
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/keystore-testbin0 -> 3895 bytes
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/logback-test.xml49
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/missingSink.json26
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/missingSource.json26
-rw-r--r--models-sim/policy-models-simulators/src/test/resources/simParameters.json95
23 files changed, 1471 insertions, 0 deletions
diff --git a/models-sim/policy-models-simulators/pom.xml b/models-sim/policy-models-simulators/pom.xml
new file mode 100644
index 000000000..5b9e4dfcc
--- /dev/null
+++ b/models-sim/policy-models-simulators/pom.xml
@@ -0,0 +1,98 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP
+ ================================================================================
+ Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============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>
+ <parent>
+ <groupId>org.onap.policy.models.sim</groupId>
+ <artifactId>policy-models-sim</artifactId>
+ <version>2.2.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>policy-models-simulators</artifactId>
+
+ <name>${project.artifactId}</name>
+ <description>A module that runs all "simulators", including DMaaP.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.models.policy-models-interactions</groupId>
+ <artifactId>simulators</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <!-- Output the version of the service -->
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/version.txt</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>**/version.txt</exclude>
+ </excludes>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-complete-tar</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/package/tarball/assembly.xml</descriptor>
+ </descriptors>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </build>
+</project>
diff --git a/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/ClassRestServerParameters.java b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/ClassRestServerParameters.java
new file mode 100644
index 000000000..030d77449
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/ClassRestServerParameters.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.policy.common.endpoints.parameters.RestServerParameters;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
+
+@Getter
+public class ClassRestServerParameters extends RestServerParameters {
+ private String providerClass;
+
+ /**
+ * Validates the parameters.
+ *
+ * @param containerName name of the parameter container
+ * @return the validation result
+ */
+ public ValidationResult validate(String containerName) {
+ // not using a BeanValidator because username and password are not required
+ if (StringUtils.isBlank(providerClass)) {
+ return new ObjectValidationResult("providerClass", providerClass, ValidationStatus.INVALID, "is empty");
+ }
+
+ return new ObjectValidationResult("providerClass", providerClass);
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/Main.java b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/Main.java
new file mode 100644
index 000000000..8333800f3
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/Main.java
@@ -0,0 +1,281 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.simulators;
+
+import java.io.FileNotFoundException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
+import lombok.AccessLevel;
+import lombok.Getter;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.endpoints.event.comm.TopicSource;
+import org.onap.policy.common.endpoints.http.server.HttpServletServer;
+import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
+import org.onap.policy.common.endpoints.parameters.TopicParameters;
+import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.network.NetworkUtil;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.common.utils.services.ServiceManagerContainer;
+import org.onap.policy.models.sim.dmaap.parameters.DmaapSimParameterGroup;
+import org.onap.policy.models.sim.dmaap.provider.DmaapSimProvider;
+import org.onap.policy.models.sim.dmaap.rest.CambriaMessageBodyHandler;
+import org.onap.policy.models.sim.dmaap.rest.TextMessageBodyHandler;
+import org.onap.policy.simulators.TopicServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class runs all simulators specified in the parameter file.
+ */
+public class Main extends ServiceManagerContainer {
+ private static final Logger logger = LoggerFactory.getLogger(Main.class);
+
+ private static final String CANNOT_CONNECT = "cannot connect to port ";
+
+ @Getter(AccessLevel.PROTECTED)
+ private static Main instance;
+
+
+ /**
+ * Runs the simulators.
+ *
+ * @param paramFile parameter file name
+ */
+ public Main(String paramFile) {
+ super(Main.class.getPackage().getName());
+
+ SimulatorParameters params = readParameters(paramFile);
+ BeanValidationResult result = params.validate("simulators");
+ if (!result.isValid()) {
+ logger.error("invalid parameters:\n{}", result.getResult());
+ throw new IllegalArgumentException("invalid simulator parameters");
+ }
+
+ DmaapSimParameterGroup dmaapProv = params.getDmaapProvider();
+ String dmaapName = dmaapProv.getName();
+ String provName = dmaapName.replace("simulator", "provider");
+
+ // dmaap provider
+ AtomicReference<DmaapSimProvider> provRef = new AtomicReference<>();
+ addAction(provName, () -> provRef.set(buildDmaapProvider(dmaapProv)), () -> provRef.get().shutdown());
+
+ // @formatter:off
+
+ // REST server simulators
+ for (ClassRestServerParameters restsim : params.getRestServers()) {
+ AtomicReference<HttpServletServer> ref = new AtomicReference<>();
+ addAction(restsim.getName(),
+ () -> ref.set(buildRestServer(dmaapName, restsim)),
+ () -> ref.get().shutdown());
+ }
+
+ // NOTE: topics must be started AFTER the (dmaap) rest servers
+
+ // topic sinks
+ AtomicReference<List<TopicSink>> sinkRef = new AtomicReference<>();
+ addAction("topic sinks", () -> sinkRef.set(buildSinks(params.getTopicSinks())),
+ () -> shutdownSinks(sinkRef.get()));
+
+ // topic sources
+ AtomicReference<List<TopicSource>> sourceRef = new AtomicReference<>();
+ addAction("topic sources", () -> sourceRef.set(buildSources(params.getTopicSources())),
+ () -> shutdownSources(sourceRef.get()));
+
+ // topic server simulators
+ for (TopicServerParameters topicsim : params.getTopicServers()) {
+ AtomicReference<TopicServer<?>> ref = new AtomicReference<>();
+ addAction(topicsim.getName(),
+ () -> ref.set(buildTopicServer(topicsim, sinkRef.get(), sourceRef.get())),
+ () -> ref.get().shutdown());
+ }
+
+ // @formatter:on
+ }
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments, the first of which is the name of the parameter file
+ */
+ public static void main(final String[] args) {
+ try {
+ if (args.length != 1) {
+ throw new IllegalArgumentException("arg(s): parameter-file-name");
+ }
+
+ instance = new Main(args[0]);
+ instance.start();
+
+ } catch (RuntimeException e) {
+ logger.error("failed to start simulators", e);
+ }
+ }
+
+ private SimulatorParameters readParameters(String paramFile) {
+ try {
+ String paramsJson = getResourceAsString(paramFile);
+ if (paramsJson == null) {
+ throw new IllegalArgumentException(new FileNotFoundException(paramFile));
+ }
+
+ String hostName = NetworkUtil.getHostname();
+ logger.info("replacing 'HOST_NAME' with {} in {}", hostName, paramFile);
+
+ paramsJson = paramsJson.replace("${HOST_NAME}", hostName);
+
+ return makeCoder().decode(paramsJson, SimulatorParameters.class);
+
+ } catch (CoderException e) {
+ throw new IllegalArgumentException("cannot decode " + paramFile, e);
+ }
+ }
+
+ private DmaapSimProvider buildDmaapProvider(DmaapSimParameterGroup params) {
+ DmaapSimProvider prov = new DmaapSimProvider(params);
+ DmaapSimProvider.setInstance(prov);
+ prov.start();
+
+ return prov;
+ }
+
+ protected List<TopicSink> buildSinks(List<TopicParameters> params) {
+ return TopicEndpointManager.getManager().addTopicSinks(params);
+ }
+
+ private void shutdownSinks(List<TopicSink> sinks) {
+ sinks.forEach(TopicSink::shutdown);
+ }
+
+ protected List<TopicSource> buildSources(List<TopicParameters> params) {
+ return TopicEndpointManager.getManager().addTopicSources(params);
+ }
+
+ private void shutdownSources(List<TopicSource> sources) {
+ sources.forEach(TopicSource::shutdown);
+ }
+
+ private HttpServletServer buildRestServer(String dmaapName, ClassRestServerParameters params) {
+ try {
+ Properties props = getServerProperties(dmaapName, params);
+ HttpServletServer testServer = makeServer(props);
+ testServer.waitedStart(5000);
+
+ String svcpfx = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + params.getName();
+ String hostName = props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX);
+
+ if (!isTcpPortOpen(hostName, testServer.getPort())) {
+ throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort());
+ }
+
+ return testServer;
+
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("interrupted while building " + params.getName(), e);
+ }
+ }
+
+ private TopicServer<?> buildTopicServer(TopicServerParameters params, List<TopicSink> sinks,
+ List<TopicSource> sources) {
+ try {
+ // find the desired sink
+ TopicSink sink = sinks.stream().filter(sink2 -> sink2.getTopic().equals(params.getSink())).findAny()
+ .orElseThrow(() -> new IllegalArgumentException("invalid sink topic " + params.getSink()));
+
+ // find the desired source
+ TopicSource source = sources.stream().filter(source2 -> source2.getTopic().equals(params.getSource()))
+ .findAny().orElseThrow(() -> new IllegalArgumentException(
+ "invalid source topic " + params.getSource()));
+
+ // create the topic server
+ return (TopicServer<?>) Class.forName(params.getProviderClass())
+ .getDeclaredConstructor(TopicSink.class, TopicSource.class).newInstance(sink, source);
+
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
+ | SecurityException | ClassNotFoundException e) {
+ throw new IllegalArgumentException("cannot create TopicServer: " + params.getName(), e);
+ }
+ }
+
+ /**
+ * Creates a set of properties, suitable for building a REST server, from the
+ * parameters.
+ *
+ * @param params parameters from which to build the properties
+ * @return a set of properties representing the given parameters
+ */
+ private static Properties getServerProperties(String dmaapName, ClassRestServerParameters params) {
+ final Properties props = new Properties();
+ props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, params.getName());
+
+ final String svcpfx = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + params.getName();
+
+ props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, params.getName());
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, params.getHost());
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX,
+ Integer.toString(params.getPort()));
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX,
+ Boolean.toString(params.isHttps()));
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX,
+ params.getProviderClass());
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "false");
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "false");
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true");
+
+ if (dmaapName.equals(params.getName())) {
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
+ String.join(",", CambriaMessageBodyHandler.class.getName(),
+ GsonMessageBodyHandler.class.getName(),
+ TextMessageBodyHandler.class.getName()));
+ } else {
+ props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, String.join(",",
+ GsonMessageBodyHandler.class.getName(), TextMessageBodyHandler.class.getName()));
+ }
+
+ return props;
+ }
+
+ // the following methods may be overridden by junit tests
+
+ protected String getResourceAsString(String resourceName) {
+ return ResourceUtils.getResourceAsString(resourceName);
+ }
+
+ protected Coder makeCoder() {
+ return new StandardCoder();
+ }
+
+ protected HttpServletServer makeServer(Properties props) {
+ return HttpServletServerFactoryInstance.getServerFactory().build(props).get(0);
+ }
+
+ protected boolean isTcpPortOpen(String hostName, int port) throws InterruptedException {
+ return NetworkUtil.isTcpPortOpen(hostName, port, 100, 200L);
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/SimulatorParameters.java b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/SimulatorParameters.java
new file mode 100644
index 000000000..c47ff8876
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/SimulatorParameters.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import java.util.LinkedList;
+import java.util.List;
+import lombok.Getter;
+import org.onap.policy.common.endpoints.parameters.TopicParameters;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.BeanValidator;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.models.sim.dmaap.parameters.DmaapSimParameterGroup;
+
+/**
+ * Simulator parameters.
+ */
+@Getter
+@NotNull
+public class SimulatorParameters {
+
+ /**
+ * Note: this is only used to capture the provider's parameters; the rest server
+ * parameters that it contains are ignored. Instead, the parameters for the rest
+ * server are contained within the {@link #restServers} entry having the same name as
+ * the provider parameters.
+ */
+ private DmaapSimParameterGroup dmaapProvider;
+
+ /**
+ * Parameters for the REST server simulators that are to be started.
+ */
+ private List<ClassRestServerParameters> restServers = new LinkedList<>();
+
+ /**
+ * Topic sinks that are used by {@link #topicServers}.
+ */
+ private List<TopicParameters> topicSinks = new LinkedList<>();
+
+ /**
+ * Topic sources that are used by {@link #topicServers}.
+ */
+ private List<TopicParameters> topicSources = new LinkedList<>();
+
+ /**
+ * Parameters for the TOPIC server simulators that are to be started.
+ */
+ private List<TopicServerParameters> topicServers = new LinkedList<>();
+
+
+ /**
+ * Validates the parameters.
+ *
+ * @param containerName name of the parameter container
+ * @return the validation result
+ */
+ public BeanValidationResult validate(String containerName) {
+ BeanValidationResult result = new BeanValidator().validateTop(containerName, this);
+
+ result.validateList("restServers", restServers, params -> params.validate("restServers"));
+ result.validateList("topicServers", topicServers, params -> params.validate("topicServers"));
+
+ return result;
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/TopicServerParameters.java b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/TopicServerParameters.java
new file mode 100644
index 000000000..8a477b232
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/TopicServerParameters.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import lombok.Getter;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.BeanValidator;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+
+@Getter
+@NotNull
+@NotBlank
+public class TopicServerParameters {
+ private String name;
+ private String providerClass;
+ private String sink;
+ private String source;
+
+
+ /**
+ * Validates the parameters.
+ *
+ * @param containerName name of the parameter container
+ * @return the validation result
+ */
+ public BeanValidationResult validate(String containerName) {
+ return new BeanValidator().validateTop(containerName, this);
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/main/package/docker/Dockerfile b/models-sim/policy-models-simulators/src/main/package/docker/Dockerfile
new file mode 100644
index 000000000..c41cd3804
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/package/docker/Dockerfile
@@ -0,0 +1,59 @@
+#
+# ============LICENSE_START=======================================================
+# ONAP
+# ================================================================================
+# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+
+#
+# Docker file to build an image that runs the simulators
+#
+
+FROM onap/policy-jre-alpine:2.0.1
+
+LABEL maintainer="Policy Team"
+
+ARG POLICY_LOGS=/var/log/onap/policy/simulators
+
+ENV POLICY_HOME /opt/app/policy
+ENV POLICY_LOGS ${POLICY_LOGS}
+
+# Create DMaaP simulator user and group
+# Add simulator-specific directories and set ownership as the simulator user
+RUN mkdir -p ${POLICY_HOME}/simulators \
+ && mkdir -p ${POLICY_HOME}/simulators/bin \
+ && mkdir -p ${POLICY_LOGS} \
+ && mkdir /packages
+
+# Unpack the tarball
+COPY policy-models-simulators-tarball.tar.gz /packages
+RUN tar xvfz /packages/policy-models-simulators-tarball.tar.gz --directory ${POLICY_HOME}/simulators \
+ && rm /packages/policy-models-simulators-tarball.tar.gz
+
+# Ensure everything has the correct permissions
+# Copy scripts simulator user area
+COPY simulators.sh ${POLICY_HOME}/simulators/bin
+RUN find /opt/app -type d -perm 755 \
+ && find /opt/app -type f -perm 644 \
+ && chmod 755 ${POLICY_HOME}/simulators/bin/* \
+ && chown -R policy:policy $POLICY_HOME $POLICY_LOGS
+
+USER policy:policy
+
+ENV PATH ${POLICY_HOME}/simulators/bin:$PATH
+ENTRYPOINT [ "bash", "simulators.sh" ]
diff --git a/models-sim/policy-models-simulators/src/main/package/docker/docker_build.sh b/models-sim/policy-models-simulators/src/main/package/docker/docker_build.sh
new file mode 100644
index 000000000..efbb1dc0f
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/package/docker/docker_build.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+#
+# ============LICENSE_START=======================================================
+# ONAP
+# ================================================================================
+# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+
+#
+# Script to build a Docker file for the simulators. The docker image
+# generated by this script should NOT be placed in the ONAP nexus, it is
+# only for testing purposes.
+#
+
+if [ -z "$SIMULATOR_HOME" ]
+then
+ SIMULATOR_HOME=$PWD
+fi
+
+# Check for the dockerfile
+if [ ! -f "$SIMULATOR_HOME/src/main/package/docker/Dockerfile" ]
+then
+ echo docker file "$SIMULATOR_HOME/src/main/package/docker/Dockerfile" not found
+ exit 1
+fi
+
+# Check for the start script
+if [ ! -f "$SIMULATOR_HOME/src/main/package/docker/simulators.sh" ]
+then
+ echo start script "$SIMULATOR_HOME/src/main/package/docker/simulators.sh" not found
+ exit 1
+fi
+
+# Check for the tarball
+tarball_count=`ls $SIMULATOR_HOME/target/policy-models-simulators-*tarball.tar.gz 2> /dev/null | wc | awk '{print $1}'`
+if [ "$tarball_count" -ne "1" ]
+then
+ echo one and only one tarball should exist in the target directory
+ exit 2
+fi
+
+# Set up the docker build
+rm -fr $SIMULATOR_HOME/target/docker
+mkdir $SIMULATOR_HOME/target/docker
+cp $SIMULATOR_HOME/src/main/package/docker/Dockerfile $SIMULATOR_HOME/target/docker
+cp $SIMULATOR_HOME/src/main/package/docker/simulators.sh $SIMULATOR_HOME/target/docker
+cp $SIMULATOR_HOME/target/policy-models-simulators-*tarball.tar.gz \
+ $SIMULATOR_HOME/target/docker/policy-models-simulators-tarball.tar.gz
+
+# Run the docker build
+cd $SIMULATOR_HOME/target
+docker build -t policy/simulators docker
diff --git a/models-sim/policy-models-simulators/src/main/package/docker/simulators.sh b/models-sim/policy-models-simulators/src/main/package/docker/simulators.sh
new file mode 100644
index 000000000..57e742708
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/package/docker/simulators.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# ============LICENSE_START=======================================================
+# ONAP
+# ================================================================================
+# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+
+if [ -z "$SIMULATOR_HOME" ]
+then
+ SIMULATOR_HOME=${POLICY_HOME}/simulators
+fi
+
+JAVA_HOME=/usr/lib/jvm/java-11-openjdk
+KEYSTORE="${SIMULATOR_HOME}/etc/ssl/policy-keystore"
+KEYSTORE_PASSWD="Pol1cy_0nap"
+TRUSTSTORE="${SIMULATOR_HOME}/etc/ssl/policy-truststore"
+TRUSTSTORE_PASSWD="Pol1cy_0nap"
+
+${JAVA_HOME}/bin/java \
+ -cp "${SIMULATOR_HOME}/etc:${SIMULATOR_HOME}/lib/*" \
+ -Dlogback.configurationFile=${SIMULATOR_HOME}/etc/logback.xml \
+ -Djavax.net.ssl.keyStore="${KEYSTORE}" \
+ -Djavax.net.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \
+ -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \
+ -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \
+ org.onap.policy.models.simulators.Main \
+ ${SIMULATOR_HOME}/etc/parameters/simParameters.json
diff --git a/models-sim/policy-models-simulators/src/main/package/tarball/assembly.xml b/models-sim/policy-models-simulators/src/main/package/tarball/assembly.xml
new file mode 100644
index 000000000..8496fd3c6
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/package/tarball/assembly.xml
@@ -0,0 +1,57 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+-->
+
+<assembly>
+ <id>tarball</id>
+ <formats>
+ <format>tar.gz</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>true</useProjectArtifact>
+ <outputDirectory>/lib</outputDirectory>
+ <unpack>false</unpack>
+ <scope>runtime</scope>
+ <includes>
+ <include>*:jar</include>
+ </includes>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <includes>
+ <include>logback.xml</include>
+ </includes>
+ <outputDirectory>etc</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ </fileSet>
+ <fileSet>
+ <directory>${project.basedir}/src/main/resources/ssl
+ </directory>
+ <includes>
+ <include>policy*</include>
+ </includes>
+ <outputDirectory>etc${file.separator}ssl</outputDirectory>
+ <lineEnding>keep</lineEnding>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/models-sim/policy-models-simulators/src/main/resources/logback.xml b/models-sim/policy-models-simulators/src/main/resources/logback.xml
new file mode 100644
index 000000000..da9821aef
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/resources/logback.xml
@@ -0,0 +1,56 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+-->
+
+<configuration scan="true" scanPeriod="30 seconds" debug="false">
+
+ <contextName>Simulators</contextName>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+ <property name="logDir" value="${POLICY_LOGS}" />
+
+ <appender name="DebugOut"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDir}/debug.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${logDir}/debug.%d{yyyy-MM-dd}.%i.log.zip
+ </fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>10</maxHistory>
+ <totalSizeCap>500MB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n
+ </Pattern>
+ </encoder>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="DebugOut" />
+ </root>
+
+ <logger name="org.eclipse.jetty" level="info" additivity="false">
+ <appender-ref ref="DebugOut" />
+ </logger>
+
+ <logger name="org.onap.policy.models.sim.dmaap" level="debug" additivity="false">
+ <appender-ref ref="DebugOut" />
+ </logger>
+
+</configuration>
diff --git a/models-sim/policy-models-simulators/src/main/resources/ssl/policy-keystore b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-keystore
new file mode 100644
index 000000000..144caf252
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-keystore
Binary files differ
diff --git a/models-sim/policy-models-simulators/src/main/resources/ssl/policy-truststore b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-truststore
new file mode 100644
index 000000000..8834ac257
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-truststore
Binary files differ
diff --git a/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/ClassRestServerParametersTest.java b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/ClassRestServerParametersTest.java
new file mode 100644
index 000000000..76637610c
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/ClassRestServerParametersTest.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+
+public class ClassRestServerParametersTest {
+
+ @Test
+ public void testValidateString() throws CoderException {
+ // some fields missing
+ ValidationResult result = new ClassRestServerParameters().validate("InvalidParams");
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+
+ // everything populated
+ SimulatorParameters simParams = new StandardCoder()
+ .decode(new File("src/test/resources/simParameters.json"), SimulatorParameters.class);
+ ClassRestServerParameters params = simParams.getRestServers().get(0);
+ assertNull(params.validate("ValidParams").getResult());
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/MainTest.java b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/MainTest.java
new file mode 100644
index 000000000..e9e8cbdec
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/MainTest.java
@@ -0,0 +1,256 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import javax.ws.rs.core.Response;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
+import org.onap.policy.common.endpoints.http.client.HttpClient;
+import org.onap.policy.common.endpoints.http.client.HttpClientConfigException;
+import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
+import org.onap.policy.common.endpoints.http.server.HttpServletServer;
+import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.network.NetworkUtil;
+
+public class MainTest {
+ private static final String PARAMETER_FILE = "simParameters.json";
+ private static final String HOST = "localhost";
+ private static final String EXPECTED_EXCEPTION = "expected exception";
+
+ private static Map<String, String> savedValues;
+
+ /**
+ * Saves system properties.
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ savedValues = new HashMap<>();
+
+ for (String prop : List.of(JettyJerseyServer.SYSTEM_KEYSTORE_PASSWORD_PROPERTY_NAME,
+ JettyJerseyServer.SYSTEM_KEYSTORE_PROPERTY_NAME,
+ JettyJerseyServer.SYSTEM_TRUSTSTORE_PASSWORD_PROPERTY_NAME,
+ JettyJerseyServer.SYSTEM_TRUSTSTORE_PROPERTY_NAME)) {
+
+ savedValues.put(prop, System.getProperty(prop));
+ }
+
+ System.setProperty(JettyJerseyServer.SYSTEM_KEYSTORE_PROPERTY_NAME, "src/test/resources/keystore-test");
+ System.setProperty(JettyJerseyServer.SYSTEM_KEYSTORE_PASSWORD_PROPERTY_NAME, "kstest");
+
+ System.setProperty(JettyJerseyServer.SYSTEM_TRUSTSTORE_PROPERTY_NAME, "src/test/resources/keystore-test");
+ System.setProperty(JettyJerseyServer.SYSTEM_TRUSTSTORE_PASSWORD_PROPERTY_NAME, "kstest");
+ }
+
+ /**
+ * Restores system properties.
+ */
+ @AfterClass
+ public static void tearDownAfterClass() {
+ for (Entry<String, String> ent : savedValues.entrySet()) {
+ if (ent.getValue() == null) {
+ System.getProperties().remove(ent.getKey());
+ } else {
+ System.setProperty(ent.getKey(), ent.getValue());
+ }
+ }
+ }
+
+ /**
+ * Shuts down the simulator instance.
+ */
+ @After
+ public void tearDown() {
+ Main main = Main.getInstance();
+ if (main != null && main.isAlive()) {
+ main.shutdown();
+ }
+ }
+
+ @Test
+ public void testConstructor() throws Exception {
+ assertThatIllegalArgumentException().isThrownBy(() -> new Main("invalidSimParameters.json"))
+ .withMessage("invalid simulator parameters");
+ }
+
+ /**
+ * Verifies that all of the simulators are brought up and that HTTPS works with at
+ * least one of them.
+ */
+ @Test
+ public void testMain() throws Exception {
+ Main.main(new String[0]);
+ assertTrue(Main.getInstance() == null || !Main.getInstance().isAlive());
+
+ Main.main(new String[] {PARAMETER_FILE});
+
+ // don't need to wait long, because buildXxx() does the wait for us
+ for (int port = 6666; port <= 6670; ++port) {
+ assertTrue("simulator on port " + port, NetworkUtil.isTcpPortOpen(HOST, port, 1, 100));
+ }
+
+ // it's sufficient to verify that one of the simulators works
+ checkAai();
+ }
+
+ private void checkAai() throws HttpClientConfigException {
+ BusTopicParams params = BusTopicParams.builder().clientName("client").hostname(HOST).port(6666).useHttps(true)
+ .allowSelfSignedCerts(true).basePath("aai").build();
+ HttpClient client = HttpClientFactoryInstance.getClientFactory().build(params);
+
+ Response response = client.get("/v8/network/generic-vnfs/generic-vnf/my-vnf");
+ assertEquals(200, response.getStatus());
+
+ String result = response.readEntity(String.class);
+ assertThat(result).contains("USUCP0PCOIL0110UJZZ01-vsrx");
+ }
+
+ /**
+ * Tests readParameters() when the file cannot be found.
+ */
+ @Test
+ public void testReadParametersNoFile() {
+ assertThatIllegalArgumentException().isThrownBy(() -> new Main("missing-file.json"))
+ .withCauseInstanceOf(FileNotFoundException.class);
+ }
+
+ /**
+ * Tests readParameters() when the json cannot be decoded.
+ */
+ @Test
+ public void testReadParametersInvalidJson() throws CoderException {
+ Coder coder = mock(Coder.class);
+ when(coder.decode(any(String.class), any())).thenThrow(new CoderException(EXPECTED_EXCEPTION));
+
+ assertThatIllegalArgumentException().isThrownBy(() -> new Main(PARAMETER_FILE) {
+ @Override
+ protected Coder makeCoder() {
+ return coder;
+ }
+ }).withCauseInstanceOf(CoderException.class);
+ }
+
+ /**
+ * Tests buildRestServer() when the server port is not open.
+ */
+ @Test
+ public void testBuildRestServerNotOpen() {
+ HttpServletServer server = mock(HttpServletServer.class);
+
+ Main main = new Main(PARAMETER_FILE) {
+ @Override
+ protected HttpServletServer makeServer(Properties props) {
+ return server;
+ }
+
+ @Override
+ protected boolean isTcpPortOpen(String hostName, int port) throws InterruptedException {
+ return false;
+ }
+ };
+
+ assertThatThrownBy(main::start).hasCauseInstanceOf(IllegalStateException.class);
+ }
+
+ /**
+ * Tests buildRestServer() when the port checker is interrupted.
+ */
+ @Test
+ public void testBuildRestServerInterrupted() throws InterruptedException {
+ HttpServletServer server = mock(HttpServletServer.class);
+
+ Main main = new Main(PARAMETER_FILE) {
+ @Override
+ protected HttpServletServer makeServer(Properties props) {
+ return server;
+ }
+
+ @Override
+ protected boolean isTcpPortOpen(String hostName, int port) throws InterruptedException {
+ throw new InterruptedException(EXPECTED_EXCEPTION);
+ }
+ };
+
+ // run in another thread so we don't interrupt this thread
+ LinkedBlockingQueue<RuntimeException> queue = new LinkedBlockingQueue<>();
+ Thread thread = new Thread(() -> {
+ try {
+ main.start();
+ } catch (RuntimeException e) {
+ queue.add(e);
+ }
+ });
+
+ thread.setDaemon(true);
+ thread.start();
+
+ RuntimeException ex = queue.poll(5, TimeUnit.SECONDS);
+ assertNotNull(ex);
+ assertTrue(ex.getCause() instanceof IllegalStateException);
+ assertThat(ex.getCause()).hasMessageStartingWith("interrupted while building");
+ }
+
+ /**
+ * Tests buildTopicServer() when the provider class is invalid.
+ */
+ @Test
+ public void testBuildTopicServerInvalidProvider() {
+ assertThatThrownBy(() -> new Main("invalidTopicServer.json").start());
+ }
+
+ /**
+ * Tests buildTopicServer() when the sink is missing.
+ */
+ @Test
+ public void testBuildTopicServerNoSink() {
+ assertThatThrownBy(() -> new Main("missingSink.json").start());
+ }
+
+ /**
+ * Tests buildTopicServer() when the sink is missing.
+ */
+ @Test
+ public void testBuildTopicServerNoSource() {
+ assertThatThrownBy(() -> new Main("missingSource.json").start());
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/SimulatorParametersTest.java b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/SimulatorParametersTest.java
new file mode 100644
index 000000000..5294ca483
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/SimulatorParametersTest.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import org.junit.Test;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+
+public class SimulatorParametersTest {
+
+ @Test
+ public void testValidate() throws CoderException {
+ // some fields missing
+ BeanValidationResult result = new SimulatorParameters().validate("InvalidParams");
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+
+ // everything populated
+ SimulatorParameters params = new StandardCoder().decode(new File("src/test/resources/simParameters.json"),
+ SimulatorParameters.class);
+ assertNull(params.validate("ValidParams").getResult());
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/TopicServerParametersTest.java b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/TopicServerParametersTest.java
new file mode 100644
index 000000000..2d182d8fb
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/java/org/onap/policy/models/simulators/TopicServerParametersTest.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.models.simulators;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+
+public class TopicServerParametersTest {
+
+ @Test
+ public void testValidateString() throws CoderException {
+ // some fields missing
+ ValidationResult result = new TopicServerParameters().validate("InvalidParams");
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+
+ // everything populated
+ SimulatorParameters simParams = new StandardCoder()
+ .decode(new File("src/test/resources/simParameters.json"), SimulatorParameters.class);
+ TopicServerParameters params = simParams.getTopicServers().get(0);
+ assertNull(params.validate("ValidParams").getResult());
+ }
+}
diff --git a/models-sim/policy-models-simulators/src/test/resources/invalidSimParameters.json b/models-sim/policy-models-simulators/src/test/resources/invalidSimParameters.json
new file mode 100644
index 000000000..2c63c0851
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/invalidSimParameters.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/models-sim/policy-models-simulators/src/test/resources/invalidTopicServer.json b/models-sim/policy-models-simulators/src/test/resources/invalidTopicServer.json
new file mode 100644
index 000000000..b3d31f6b4
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/invalidTopicServer.json
@@ -0,0 +1,35 @@
+{
+ "dmaapProvider": {
+ "name": "DMaaP simulator",
+ "topicSweepSec": 300,
+ "restServerParameters": {
+
+ }
+ },
+ "topicSinks": [
+ {
+ "topic": "APPC-LCM-READ",
+ "servers": ["localhost"],
+ "port": 3905,
+ "topicCommInfrastructure": "DMAAP",
+ "https": true
+ }
+ ],
+ "topicSources": [
+ {
+ "topic": "APPC-LCM-WRITE",
+ "servers": ["localhost"],
+ "port": 3905,
+ "topicCommInfrastructure": "DMAAP",
+ "https": true
+ }
+ ],
+ "topicServers": [
+ {
+ "name": "Invalid Topic simulator",
+ "providerClass": "org.onap.policy.simulators.InvalidTopicServer",
+ "sink": "APPC-LCM-READ",
+ "source": "APPC-LCM-WRITE"
+ }
+ ]
+}
diff --git a/models-sim/policy-models-simulators/src/test/resources/keystore-test b/models-sim/policy-models-simulators/src/test/resources/keystore-test
new file mode 100644
index 000000000..5820e0f0c
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/keystore-test
Binary files differ
diff --git a/models-sim/policy-models-simulators/src/test/resources/logback-test.xml b/models-sim/policy-models-simulators/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..e599a94a8
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/logback-test.xml
@@ -0,0 +1,49 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+-->
+
+<configuration scan="true" scanPeriod="30 seconds"
+ debug="false">
+
+ <contextName>Simulators</contextName>
+ <statusListener
+ class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <!-- USE FOR STD OUT ONLY -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.eclipse.jetty" level="info"
+ additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.onap.policy.models.sim.dmaap" level="debug"
+ additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+</configuration>
diff --git a/models-sim/policy-models-simulators/src/test/resources/missingSink.json b/models-sim/policy-models-simulators/src/test/resources/missingSink.json
new file mode 100644
index 000000000..e7d63e04f
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/missingSink.json
@@ -0,0 +1,26 @@
+{
+ "dmaapProvider": {
+ "name": "DMaaP simulator",
+ "topicSweepSec": 300,
+ "restServerParameters": {
+
+ }
+ },
+ "topicSources": [
+ {
+ "topic": "APPC-LCM-WRITE",
+ "servers": ["localhost"],
+ "port": 3905,
+ "topicCommInfrastructure": "DMAAP",
+ "https": true
+ }
+ ],
+ "topicServers": [
+ {
+ "name": "APPC-LCM simulator",
+ "providerClass": "org.onap.policy.simulators.AppcLcmTopicServer",
+ "sink": "APPC-LCM-READ",
+ "source": "APPC-LCM-WRITE"
+ }
+ ]
+}
diff --git a/models-sim/policy-models-simulators/src/test/resources/missingSource.json b/models-sim/policy-models-simulators/src/test/resources/missingSource.json
new file mode 100644
index 000000000..0f02e4095
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/missingSource.json
@@ -0,0 +1,26 @@
+{
+ "dmaapProvider": {
+ "name": "DMaaP simulator",
+ "topicSweepSec": 300,
+ "restServerParameters": {
+
+ }
+ },
+ "topicSinks": [
+ {
+ "topic": "APPC-LCM-READ",
+ "servers": ["localhost"],
+ "port": 3905,
+ "topicCommInfrastructure": "DMAAP",
+ "https": true
+ }
+ ],
+ "topicServers": [
+ {
+ "name": "APPC-LCM simulator",
+ "providerClass": "org.onap.policy.simulators.AppcLcmTopicServer",
+ "sink": "APPC-LCM-READ",
+ "source": "APPC-LCM-WRITE"
+ }
+ ]
+}
diff --git a/models-sim/policy-models-simulators/src/test/resources/simParameters.json b/models-sim/policy-models-simulators/src/test/resources/simParameters.json
new file mode 100644
index 000000000..c7abb2973
--- /dev/null
+++ b/models-sim/policy-models-simulators/src/test/resources/simParameters.json
@@ -0,0 +1,95 @@
+{
+ "dmaapProvider": {
+ "name": "DMaaP simulator",
+ "topicSweepSec": 300,
+ "restServerParameters": {
+
+ }
+ },
+ "restServers": [
+ {
+ "name": "DMaaP simulator",
+ "providerClass": "org.onap.policy.models.sim.dmaap.rest.DmaapSimRestControllerV1",
+ "host": "localhost",
+ "port": 3905,
+ "https": true
+ },
+ {
+ "name": "A&AI simulator",
+ "providerClass": "org.onap.policy.simulators.AaiSimulatorJaxRs",
+ "host": "localhost",
+ "port": 6666,
+ "https": true
+ },
+ {
+ "name": "Guard simulator",
+ "providerClass": "org.onap.policy.simulators.GuardSimulatorJaxRs",
+ "host": "localhost",
+ "port": 6667,
+ "https": true
+ },
+ {
+ "name": "SDNC simulator",
+ "providerClass": "org.onap.policy.simulators.SdncSimulatorJaxRs",
+ "host": "localhost",
+ "port": 6668,
+ "https": true
+ },
+ {
+ "name": "SO simulator",
+ "providerClass": "org.onap.policy.simulators.SoSimulatorJaxRs",
+ "host": "localhost",
+ "port": 6669,
+ "https": true
+ },
+ {
+ "name": "VFC simulator",
+ "providerClass": "org.onap.policy.simulators.VfcSimulatorJaxRs",
+ "host": "localhost",
+ "port": 6670,
+ "https": true
+ }
+ ],
+ "topicSinks": [
+ {
+ "topic": "APPC-CL",
+ "servers": ["localhost"],
+ "topicCommInfrastructure": "DMAAP",
+ "useHttps": true
+ },
+ {
+ "topic": "APPC-LCM-READ",
+ "servers": ["localhost"],
+ "topicCommInfrastructure": "DMAAP",
+ "useHttps": true
+ }
+ ],
+ "topicSources": [
+ {
+ "topic": "APPC-CL",
+ "servers": ["localhost"],
+ "topicCommInfrastructure": "DMAAP",
+ "useHttps": true
+ },
+ {
+ "topic": "APPC-LCM-WRITE",
+ "servers": ["localhost"],
+ "topicCommInfrastructure": "DMAAP",
+ "useHttps": true
+ }
+ ],
+ "topicServers": [
+ {
+ "name": "APPC Legacy simulator",
+ "providerClass": "org.onap.policy.simulators.AppcLegacyTopicServer",
+ "sink": "APPC-CL",
+ "source": "APPC-CL"
+ },
+ {
+ "name": "APPC-LCM simulator",
+ "providerClass": "org.onap.policy.simulators.AppcLcmTopicServer",
+ "sink": "APPC-LCM-READ",
+ "source": "APPC-LCM-WRITE"
+ }
+ ]
+}