From f586da49681a510c79729d94a4565694d952b83b Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 26 Jun 2020 16:59:40 -0400 Subject: Add CDS simulator to policy-models Added CDS simulator to policy-models. Added a test case to the CDS Actor to verify that it works with the simulator. Issue-ID: POLICY-2676 Change-Id: I9b10de3bde93c69e82df983f77eecc253de8a1a2 Signed-off-by: Jim Hahn --- models-interactions/model-simulators/pom.xml | 5 + .../org/onap/policy/simulators/CdsSimulator.java | 104 +++++++++++++++++++ .../simulators/SimulatorRuntimeException.java | 41 ++++++++ .../main/java/org/onap/policy/simulators/Util.java | 46 +++++---- .../cds/CreateSubscriptionResponseEvent.json | 29 ++++++ .../onap/policy/simulators/CdsSimulatorTest.java | 114 +++++++++++++++++++++ .../org/onap/policy/simulators/ExceptionsTest.java | 37 +++++++ .../onap/policy/simulators/cds/cds.request.json | 14 +++ 8 files changed, 372 insertions(+), 18 deletions(-) create mode 100644 models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/CdsSimulator.java create mode 100644 models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/SimulatorRuntimeException.java create mode 100644 models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/cds/CreateSubscriptionResponseEvent.json create mode 100644 models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/CdsSimulatorTest.java create mode 100644 models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/ExceptionsTest.java create mode 100644 models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/cds/cds.request.json (limited to 'models-interactions/model-simulators') diff --git a/models-interactions/model-simulators/pom.xml b/models-interactions/model-simulators/pom.xml index 92c26c2b7..f0afa54c0 100644 --- a/models-interactions/model-simulators/pom.xml +++ b/models-interactions/model-simulators/pom.xml @@ -54,6 +54,11 @@ appc ${project.version} + + org.onap.policy.models.policy-models-interactions.model-impl + cds + ${project.version} + org.onap.policy.models.policy-models-interactions.model-impl appclcm diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/CdsSimulator.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/CdsSimulator.java new file mode 100644 index 000000000..dbbaa1681 --- /dev/null +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/CdsSimulator.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * Modifications 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.simulators; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; +import io.grpc.Server; +import io.grpc.netty.NettyServerBuilder; +import io.grpc.stub.StreamObserver; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import lombok.Getter; +import org.apache.commons.io.IOUtils; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput.Builder; + +public class CdsSimulator { + @Getter + private final int port; + + private final Server server; + + /** + * Constructs the object, but does not start it. + * + * @param host host name of the server + * @param port port of the server + */ + public CdsSimulator(String host, int port) { + this.port = port; + + BluePrintProcessingServiceImplBase testCdsBlueprintServerImpl = new BluePrintProcessingServiceImplBase() { + + @Override + public StreamObserver process( + final StreamObserver responseObserver) { + + return new StreamObserver() { + + @Override + public void onNext(final ExecutionServiceInput executionServiceInput) { + try { + String responseString = IOUtils.toString( + getClass().getResource("cds/CreateSubscriptionResponseEvent.json"), + StandardCharsets.UTF_8); + Builder builder = ExecutionServiceOutput.newBuilder(); + JsonFormat.parser().ignoringUnknownFields().merge(responseString, builder); + responseObserver.onNext(builder.build()); + + } catch (InvalidProtocolBufferException e) { + throw new SimulatorRuntimeException("Cannot convert ExecutionServiceOutput output", e); + + } catch (IOException e) { + throw new SimulatorRuntimeException("Cannot read ExecutionServiceOutput from file", e); + } + } + + @Override + public void onError(final Throwable throwable) { + responseObserver.onError(throwable); + } + + @Override + public void onCompleted() { + responseObserver.onCompleted(); + } + }; + } + }; + + server = NettyServerBuilder.forAddress(new InetSocketAddress(host, port)).addService(testCdsBlueprintServerImpl) + .build(); + } + + public void start() throws IOException { + server.start(); + } + + public void stop() { + server.shutdown(); + } +} diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/SimulatorRuntimeException.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/SimulatorRuntimeException.java new file mode 100644 index 000000000..b97e4d9f7 --- /dev/null +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/SimulatorRuntimeException.java @@ -0,0 +1,41 @@ +/*- + * ============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; + +public class SimulatorRuntimeException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public SimulatorRuntimeException() { + super(); + } + + public SimulatorRuntimeException(String message) { + super(message); + } + + public SimulatorRuntimeException(Throwable cause) { + super(cause); + } + + public SimulatorRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/Util.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/Util.java index 5cb518f4e..efc40367b 100644 --- a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/Util.java +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/Util.java @@ -21,6 +21,7 @@ package org.onap.policy.simulators; +import java.io.IOException; import java.util.Properties; import org.onap.policy.common.endpoints.http.server.HttpServletServer; import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; @@ -46,6 +47,7 @@ public class Util { public static final int VFCSIM_SERVER_PORT = 6668; public static final int GUARDSIM_SERVER_PORT = 6669; public static final int SDNCSIM_SERVER_PORT = 6670; + public static final int CDSSIM_SERVER_PORT = 6671; public static final int DMAAPSIM_SERVER_PORT = 3904; private static final String CANNOT_PROCESS_PARAMETERS = "cannot parse parameters "; @@ -67,9 +69,21 @@ public class Util { .build(AAISIM_SERVER_NAME, LOCALHOST, AAISIM_SERVER_PORT, "/", false, true); testServer.addServletClass("/*", AaiSimulatorJaxRs.class.getName()); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); + return testServer; + } + + /** + * Build a CDS simulator. + * + * @return the simulator + * @throws InterruptedException if a thread is interrupted + * @throws IOException if an I/O error occurs + */ + public static CdsSimulator buildCdsSim() throws InterruptedException, IOException { + final CdsSimulator testServer = new CdsSimulator(LOCALHOST, CDSSIM_SERVER_PORT); + testServer.start(); + waitForServerToListen(testServer.getPort()); return testServer; } @@ -84,9 +98,7 @@ public class Util { .build(SDNCSIM_SERVER_NAME, LOCALHOST, SDNCSIM_SERVER_PORT, "/", false, true); testServer.addServletClass("/*", SdncSimulatorJaxRs.class.getName()); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); return testServer; } @@ -102,9 +114,7 @@ public class Util { .build(SOSIM_SERVER_NAME, LOCALHOST, SOSIM_SERVER_PORT, "/", false, true); testServer.addServletClass("/*", SoSimulatorJaxRs.class.getName()); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); return testServer; } @@ -119,9 +129,7 @@ public class Util { .build(VFCSIM_SERVER_NAME, LOCALHOST, VFCSIM_SERVER_PORT, "/", false, true); testServer.addServletClass("/*", VfcSimulatorJaxRs.class.getName()); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); return testServer; } @@ -136,9 +144,7 @@ public class Util { LOCALHOST, GUARDSIM_SERVER_PORT, "/", false, true); testServer.addServletClass("/*", GuardSimulatorJaxRs.class.getName()); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); return testServer; } @@ -170,9 +176,13 @@ public class Util { HttpServletServer testServer = HttpServletServerFactoryInstance.getServerFactory().build(props).get(0); testServer.waitedStart(5000); - if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 50, 1000L)) { - throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); - } + waitForServerToListen(testServer.getPort()); return testServer; } + + private static void waitForServerToListen(int port) throws InterruptedException { + if (!NetworkUtil.isTcpPortOpen(LOCALHOST, port, 200, 250L)) { + throw new IllegalStateException(CANNOT_CONNECT + port); + } + } } diff --git a/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/cds/CreateSubscriptionResponseEvent.json b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/cds/CreateSubscriptionResponseEvent.json new file mode 100644 index 000000000..adb51adcb --- /dev/null +++ b/models-interactions/model-simulators/src/main/resources/org/onap/policy/simulators/cds/CreateSubscriptionResponseEvent.json @@ -0,0 +1,29 @@ +{ + "commonHeader": { + "timestamp": "2020-03-20T14:00:25.217Z", + "requestId": "123456-1000", + "subRequestId": "sub-123456-1000", + "flag": { + }, + "originatorId": "sdnc" + }, + "actionIdentifiers": { + "blueprintName": "pm_control", + "blueprintVersion": "1.0.0", + "actionName": "create-subscription", + "mode": "sync" + }, + "status": { + "code": 200, + "message": "success", + "eventType": "EVENT_COMPONENT_EXECUTED", + "timestamp": "Fri Mar 20 14:00:26 GMT 2020" + }, + "payload": { + "create-subscription-response": { + "odl-response": { + "status": "success" + } + } + } +} \ No newline at end of file diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/CdsSimulatorTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/CdsSimulatorTest.java new file mode 100644 index 000000000..5f82b7e94 --- /dev/null +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/CdsSimulatorTest.java @@ -0,0 +1,114 @@ +/*- + * ============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.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import io.grpc.ManagedChannel; +import io.grpc.internal.DnsNameResolverProvider; +import io.grpc.internal.PickFirstLoadBalancerProvider; +import io.grpc.netty.NettyChannelBuilder; +import io.grpc.stub.StreamObserver; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc.BluePrintProcessingServiceStub; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput; +import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput; +import org.onap.policy.common.utils.coder.StandardCoder; + +public class CdsSimulatorTest { + private static final StandardCoder coder = new StandardCoder(); + + private CdsSimulator sim; + + @Before + public void setUp() throws Exception { + sim = Util.buildCdsSim(); + } + + @After + public void tearDown() { + sim.stop(); + } + + @Test + public void test() throws Exception { + String reqstr = IOUtils.toString(getClass().getResource("cds/cds.request.json"), StandardCharsets.UTF_8); + ExecutionServiceInput request = coder.decode(reqstr, ExecutionServiceInput.class); + + ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", sim.getPort()) + .nameResolverFactory(new DnsNameResolverProvider()) + .loadBalancerFactory(new PickFirstLoadBalancerProvider()).usePlaintext().build(); + + try { + final CompletableFuture future = new CompletableFuture<>(); + final CountDownLatch completed = new CountDownLatch(1); + + BluePrintProcessingServiceStub asyncStub = BluePrintProcessingServiceGrpc.newStub(channel); + + StreamObserver responseObserver = new StreamObserver() { + @Override + public void onNext(ExecutionServiceOutput output) { + future.complete(output); + } + + @Override + public void onError(Throwable throwable) { + future.completeExceptionally(throwable); + } + + @Override + public void onCompleted() { + completed.countDown(); + } + }; + + StreamObserver requestObserver = asyncStub.process(responseObserver); + try { + // publish the message + requestObserver.onNext(request); + + // indicate that the request is done + requestObserver.onCompleted(); + + } catch (RuntimeException e) { + requestObserver.onError(e); + } + + // wait for it to complete + assertTrue(completed.await(5, TimeUnit.SECONDS)); + + ExecutionServiceOutput result = future.get(); + assertEquals(200, result.getStatus().getCode()); + + } finally { + channel.shutdown(); + } + } +} diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/ExceptionsTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/ExceptionsTest.java new file mode 100644 index 000000000..e3d91f0f2 --- /dev/null +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/ExceptionsTest.java @@ -0,0 +1,37 @@ +/*- + * ============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.junit.Assert.assertEquals; + +import org.junit.Test; +import org.onap.policy.common.utils.test.ExceptionsTester; + +/** + * Tests XxxException classes. + */ +public class ExceptionsTest { + + @Test + public void testSimulatorRuntimeException() { + assertEquals(4, new ExceptionsTester().test(SimulatorRuntimeException.class)); + } +} diff --git a/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/cds/cds.request.json b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/cds/cds.request.json new file mode 100644 index 000000000..37e8b05ce --- /dev/null +++ b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/cds/cds.request.json @@ -0,0 +1,14 @@ +{ + "commonHeader": { + "originatorId": "POLICY", + "requestId": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65", + "subRequestId": "111be3d2-6c12-4f4b-a3e7-c349acced200" + }, + "actionIdentifiers": { + "blueprintName": "pm_control", + "blueprintVersion": "1.0.0", + "actionName": "create-subscription", + "mode": "sync" + }, + "payload": {} +} -- cgit 1.2.3-korg