From: Jim Hahn Date: Tue, 17 Mar 2020 21:41:59 +0000 (-0400) Subject: Add docker file for all simulators X-Git-Tag: 2.2.1~4^2~1 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=bc02433cc5292c5272dc084db8044bb4c8140135;p=policy%2Fmodels.git Add docker file for all simulators Some CSITs may require multiple simulators. This adds a class that will start all of the simulators. A tarball is generated from which a docker image can be built. Added simulators for Topics: appc and appc-lcm. Fixed licenses in files in packages directory. Fixed per review comments: - add version to Dockerfile Issue-ID: POLICY-2434 Signed-off-by: Jim Hahn Change-Id: Id7aa9cb5a5874f7b4185273ab0d2c074198554ff --- diff --git a/models-interactions/model-simulators/pom.xml b/models-interactions/model-simulators/pom.xml index fc9fe12f3..d74aa05ad 100644 --- a/models-interactions/model-simulators/pom.xml +++ b/models-interactions/model-simulators/pom.xml @@ -1,6 +1,6 @@ - - 4.0.0 + + 4.0.0 - - org.onap.policy.models - policy-models-interactions - 2.2.1-SNAPSHOT - + + org.onap.policy.models + policy-models-interactions + 2.2.1-SNAPSHOT + - org.onap.policy.models.policy-models-interactions - simulators + org.onap.policy.models.policy-models-interactions + simulators - - - org.onap.policy.common - policy-endpoints - ${policy.common.version} - - - junit - junit - test - - - org.onap.policy.models.policy-models-interactions.model-impl - aai - ${project.version} - - - org.onap.policy.models.policy-models-interactions.model-impl - so - ${project.version} - - - org.onap.policy.models.policy-models-interactions.model-impl - vfc - ${project.version} - test - - - com.google.code.gson - gson - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - sdnc - ${project.version} - - - org.onap.policy.models - policy-models-decisions - ${project.version} - - - org.onap.policy.models.sim - policy-models-sim-dmaap - ${project.version} - - + + + org.onap.policy.common + policy-endpoints + ${policy.common.version} + + + junit + junit + test + + + org.onap.policy.models.policy-models-interactions.model-impl + aai + ${project.version} + + + org.onap.policy.models.policy-models-interactions.model-impl + appc + ${project.version} + + + org.onap.policy.models.policy-models-interactions.model-impl + appclcm + ${project.version} + + + org.onap.policy.models.policy-models-interactions.model-impl + so + ${project.version} + + + org.onap.policy.models.policy-models-interactions.model-impl + vfc + ${project.version} + test + + + com.google.code.gson + gson + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + sdnc + ${project.version} + + + org.onap.policy.models + policy-models-decisions + ${project.version} + + + org.onap.policy.models.sim + policy-models-sim-dmaap + ${project.version} + + + org.powermock + powermock-api-mockito2 + test + + diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLcmTopicServer.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLcmTopicServer.java new file mode 100644 index 000000000..df4cbb31e --- /dev/null +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLcmTopicServer.java @@ -0,0 +1,42 @@ +/*- + * ============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.simulators; + +import org.onap.policy.appclcm.AppcLcmDmaapWrapper; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * APPC-LCM topic server. + */ +public class AppcLcmTopicServer extends TopicServer { + public AppcLcmTopicServer(TopicSink sink, TopicSource source) { + super(sink, source, new StandardCoder(), AppcLcmDmaapWrapper.class); + } + + @Override + protected String process(AppcLcmDmaapWrapper request) { + String response = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appclcm/appc.lcm.success.json"); + return response.replace("${replaceMe}", request.getBody().getInput().getCommonHeader().getSubRequestId()); + } +} diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLegacyTopicServer.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLegacyTopicServer.java new file mode 100644 index 000000000..5ebd3bd2a --- /dev/null +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLegacyTopicServer.java @@ -0,0 +1,42 @@ +/*- + * ============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.simulators; + +import org.onap.policy.appc.Request; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.coder.StandardCoderInstantAsMillis; +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * Legacy APPC topic server. + */ +public class AppcLegacyTopicServer extends TopicServer { + public AppcLegacyTopicServer(TopicSink sink, TopicSource source) { + super(sink, source, new StandardCoderInstantAsMillis(), Request.class); + } + + @Override + protected String process(Request request) { + String response = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appc/appc.legacy.success.json"); + return response.replace("${replaceMe}", request.getCommonHeader().getSubRequestId()); + } +} diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/TopicServer.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/TopicServer.java new file mode 100644 index 000000000..0abe5f421 --- /dev/null +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/TopicServer.java @@ -0,0 +1,72 @@ +/*- + * ============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.simulators; + +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicListener; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; + +/** + * Server whose requests are received from a topic, and whose responses are sent to a + * topic. + */ +public abstract class TopicServer implements TopicListener { + private final TopicSink sink; + private final TopicSource source; + private final Coder coder; + private final Class reqClass; + + /** + * Constructs the object. + * + * @param sink sink to which responses should be published + * @param source source from which requests arrive + */ + public TopicServer(TopicSink sink, TopicSource source, Coder coder, Class reqClass) { + this.sink = sink; + this.source = source; + this.coder = coder; + this.reqClass = reqClass; + + source.register(this); + } + + public void shutdown() { + source.unregister(this); + } + + @Override + public void onTopicEvent(CommInfrastructure commType, String topic, String request) { + Q req; + try { + req = coder.decode(request, reqClass); + } catch (CoderException e) { + throw new IllegalArgumentException("cannot decode request from " + source.getTopic()); + } + + sink.send(process(req)); + } + + protected abstract String process(Q request); +} diff --git a/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appc/appc.legacy.success.json b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appc/appc.legacy.success.json new file mode 100644 index 000000000..eb19c6832 --- /dev/null +++ b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appc/appc.legacy.success.json @@ -0,0 +1,17 @@ +{ + "CommonHeader": { + "TimeStamp": 1506051879001, + "APIver": "1.01", + "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65", + "SubRequestID": "${replaceMe}", + "RequestTrack": [], + "Flags": [] + }, + "Status": { + "Code": 400, + "Value": "SUCCESS" + }, + "Payload": { + "generic-vnf.vnf-id": "jimmy-test-vnf2" + } +} diff --git a/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appclcm/appc.lcm.success.json b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appclcm/appc.lcm.success.json new file mode 100644 index 000000000..331021798 --- /dev/null +++ b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/appclcm/appc.lcm.success.json @@ -0,0 +1,22 @@ +{ + "body": { + "output": { + "common-header": { + "timestamp": "2017-08-25T21:06:23.037Z", + "api-ver": "5.00", + "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "sub-request-id": "${replaceMe}", + "flags": {} + }, + "status": { + "code": 400, + "message": "Restart Successful" + } + } + }, + "version": "2.0", + "rpc-name": "restart", + "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-1", + "type": "response" +} diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLcmTopicServerTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLcmTopicServerTest.java new file mode 100644 index 000000000..bc803154f --- /dev/null +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLcmTopicServerTest.java @@ -0,0 +1,69 @@ +/*- + * ============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.simulators; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.resources.ResourceUtils; + +public class AppcLcmTopicServerTest { + private static final String MY_TOPIC = "my-topic"; + + @Mock + private TopicSink sink; + @Mock + private TopicSource source; + + private AppcLcmTopicServer server; + + /** + * Sets up. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + server = new AppcLcmTopicServer(sink, source); + } + + @Test + public void testProcessAppcLcmDmaapWrapper() { + String request = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appclcm/appc.lcm.request.json"); + assertNotNull(request); + + server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, request); + + ArgumentCaptor respCaptor = ArgumentCaptor.forClass(String.class); + verify(sink).send(respCaptor.capture()); + + assertThat(respCaptor.getValue()).contains("111be3d2").doesNotContain("replaceMe"); + } +} diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLegacyTopicServerTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLegacyTopicServerTest.java new file mode 100644 index 000000000..57d574a0b --- /dev/null +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLegacyTopicServerTest.java @@ -0,0 +1,69 @@ +/*- + * ============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.simulators; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.resources.ResourceUtils; + +public class AppcLegacyTopicServerTest { + private static final String MY_TOPIC = "my-topic"; + + @Mock + private TopicSink sink; + @Mock + private TopicSource source; + + private AppcLegacyTopicServer server; + + /** + * Sets up. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + server = new AppcLegacyTopicServer(sink, source); + } + + @Test + public void testProcessAppcLcmDmaapWrapper() { + String request = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appc/appc.legacy.request.json"); + assertNotNull(request); + + server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, request); + + ArgumentCaptor respCaptor = ArgumentCaptor.forClass(String.class); + verify(sink).send(respCaptor.capture()); + + assertThat(respCaptor.getValue()).contains("111be3d2").doesNotContain("replaceMe"); + } +} diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/TopicServerTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/TopicServerTest.java new file mode 100644 index 000000000..6e176423e --- /dev/null +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/TopicServerTest.java @@ -0,0 +1,104 @@ +/*- + * ============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.simulators; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.utils.coder.StandardCoder; + +public class TopicServerTest { + private static final String MY_TOPIC = "my-topic"; + private static final String TEXT = "hello"; + private static final String RESPONSE = "world"; + + @Mock + private TopicSink sink; + @Mock + private TopicSource source; + + private MyServer server; + + /** + * Sets up. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + server = new MyServer(); + } + + @Test + public void testConstructor() { + verify(source).register(server); + } + + @Test + public void testShutdown() { + server.shutdown(); + verify(source).unregister(server); + } + + @Test + public void testOnTopicEvent() { + server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, "{\"text\": \"hello\"}"); + verify(sink).send(RESPONSE); + } + + /** + * Tests onTopicEvent() when the coder throws an exception. + */ + @Test + public void testOnTopicEventException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, "{invalid json")); + + verify(sink, never()).send(any()); + } + + + private class MyRequest { + private String text; + } + + private class MyServer extends TopicServer { + public MyServer() { + super(sink, source, new StandardCoder(), MyRequest.class); + } + + @Override + protected String process(MyRequest request) { + assertEquals(TEXT, request.text); + return RESPONSE; + } + } +} diff --git a/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appc/appc.legacy.request.json b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appc/appc.legacy.request.json new file mode 100644 index 000000000..8b3b73a88 --- /dev/null +++ b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appc/appc.legacy.request.json @@ -0,0 +1,10 @@ +{ + "CommonHeader": { + "TimeStamp": 1506051879001, + "APIver": "1.01", + "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65", + "SubRequestID": "111be3d2-6c12-4f4b-a3e7-c349acced200", + "RequestTrack": [], + "Flags": [] + } +} diff --git a/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appclcm/appc.lcm.request.json b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appclcm/appc.lcm.request.json new file mode 100644 index 000000000..cf2ebd521 --- /dev/null +++ b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appclcm/appc.lcm.request.json @@ -0,0 +1,17 @@ +{ + "body": { + "input": { + "common-header": { + "timestamp": "2017-08-25T21:06:23.037Z", + "api-ver": "5.00", + "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "sub-request-id": "111be3d2-6c12-4f4b-a3e7-c349acced200", + "flags": {} + } + } + }, + "version": "2.0", + "rpc-name": "restart", + "type": "request" +} 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 @@ + + + + 4.0.0 + + org.onap.policy.models.sim + policy-models-sim + 2.2.1-SNAPSHOT + + + policy-models-simulators + + ${project.artifactId} + A module that runs all "simulators", including DMaaP. + + + + org.onap.policy.models.policy-models-interactions + simulators + ${project.version} + + + junit + junit + test + + + org.powermock + powermock-api-mockito2 + test + + + + + + + + src/main/resources + true + + **/version.txt + + + + src/main/resources + false + + **/version.txt + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + generate-complete-tar + package + + single + + + + src/main/package/tarball/assembly.xml + + ${project.artifactId}-${project.version} + + + + + + + + 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 provRef = new AtomicReference<>(); + addAction(provName, () -> provRef.set(buildDmaapProvider(dmaapProv)), () -> provRef.get().shutdown()); + + // @formatter:off + + // REST server simulators + for (ClassRestServerParameters restsim : params.getRestServers()) { + AtomicReference 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> sinkRef = new AtomicReference<>(); + addAction("topic sinks", () -> sinkRef.set(buildSinks(params.getTopicSinks())), + () -> shutdownSinks(sinkRef.get())); + + // topic sources + AtomicReference> sourceRef = new AtomicReference<>(); + addAction("topic sources", () -> sourceRef.set(buildSources(params.getTopicSources())), + () -> shutdownSources(sourceRef.get())); + + // topic server simulators + for (TopicServerParameters topicsim : params.getTopicServers()) { + AtomicReference> 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 buildSinks(List params) { + return TopicEndpointManager.getManager().addTopicSinks(params); + } + + private void shutdownSinks(List sinks) { + sinks.forEach(TopicSink::shutdown); + } + + protected List buildSources(List params) { + return TopicEndpointManager.getManager().addTopicSources(params); + } + + private void shutdownSources(List 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 sinks, + List 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 restServers = new LinkedList<>(); + + /** + * Topic sinks that are used by {@link #topicServers}. + */ + private List topicSinks = new LinkedList<>(); + + /** + * Topic sources that are used by {@link #topicServers}. + */ + private List topicSources = new LinkedList<>(); + + /** + * Parameters for the TOPIC server simulators that are to be started. + */ + private List 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 @@ + + + + tarball + + tar.gz + + false + + + true + /lib + false + runtime + + *:jar + + + + + + ${project.basedir}/src/main/resources + + logback.xml + + etc + unix + + + ${project.basedir}/src/main/resources/ssl + + + policy* + + etc${file.separator}ssl + keep + + + 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 @@ + + + + + Simulators + + + + + ${logDir}/debug.log + + ${logDir}/debug.%d{yyyy-MM-dd}.%i.log.zip + + 50MB + 10 + 500MB + + + %d %contextName [%t] %level %logger{36} - %msg%n + + + + + + + + + + + + + + + + + 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 Binary files /dev/null and b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-keystore 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 Binary files /dev/null and b/models-sim/policy-models-simulators/src/main/resources/ssl/policy-truststore 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 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 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 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 Binary files /dev/null and b/models-sim/policy-models-simulators/src/test/resources/keystore-test 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 @@ + + + + + Simulators + + + + + + %d %contextName [%t] %level %logger{36} - %msg%n + + + + + + + + + + + + + + + + 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" + } + ] +} diff --git a/models-sim/pom.xml b/models-sim/pom.xml index 5bcb87807..213ff1f74 100644 --- a/models-sim/pom.xml +++ b/models-sim/pom.xml @@ -39,5 +39,6 @@ models-sim-dmaap policy-models-sim-pdp + policy-models-simulators