Bug fixes in models simulators 92/104092/2
authorJim Hahn <jrh3@att.com>
Fri, 20 Mar 2020 19:53:47 +0000 (15:53 -0400)
committerJim Hahn <jrh3@att.com>
Fri, 20 Mar 2020 20:23:28 +0000 (16:23 -0400)
Fixed these issues:
- topics weren't started
- appc topics were reversed
- prevent appc simulator from responding to a response (i.e., infinite
  loop)

Issue-ID: POLICY-2434
Signed-off-by: Jim Hahn <jrh3@att.com>
Change-Id: I1f43be72d35f874fec98f48f1a112c055c00eee5

models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/AppcLegacyTopicServer.java
models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/TopicServer.java
models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/AppcLegacyTopicServerTest.java
models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/TopicServerTest.java
models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/appc/appc.legacy.request.json
models-sim/policy-models-simulators/src/main/java/org/onap/policy/models/simulators/Main.java
models-sim/policy-models-simulators/src/test/resources/appc.lcm.request.json [new file with mode: 0644]
models-sim/policy-models-simulators/src/test/resources/simParameters.json

index 5ebd3bd..0c25978 100644 (file)
@@ -36,6 +36,15 @@ public class AppcLegacyTopicServer extends TopicServer<Request> {
 
     @Override
     protected String process(Request request) {
+        /*
+         * The request and response are on the same topic, thus this may be invoked with a
+         * request or with a response object. If the "action" is null, then we know it's a
+         * response.
+         */
+        if (request.getAction() == null) {
+            return null;
+        }
+
         String response = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appc/appc.legacy.success.json");
         return response.replace("${replaceMe}", request.getCommonHeader().getSubRequestId());
     }
index 0abe5f4..4c01511 100644 (file)
@@ -65,8 +65,17 @@ public abstract class TopicServer<Q> implements TopicListener {
             throw new IllegalArgumentException("cannot decode request from " + source.getTopic());
         }
 
-        sink.send(process(req));
+        String resp = process(req);
+        if (resp != null) {
+            sink.send(resp);
+        }
     }
 
+    /**
+     * Processes a request.
+     *
+     * @param request request to be processed
+     * @return the response, or {@code null} if no response is to be sent
+     */
     protected abstract String process(Q request);
 }
index 57d574a..c3c3195 100644 (file)
@@ -22,6 +22,8 @@ package org.onap.policy.simulators;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
 import org.junit.Before;
@@ -55,7 +57,7 @@ public class AppcLegacyTopicServerTest {
     }
 
     @Test
-    public void testProcessAppcLcmDmaapWrapper() {
+    public void testProcess() {
         String request = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appc/appc.legacy.request.json");
         assertNotNull(request);
 
@@ -66,4 +68,18 @@ public class AppcLegacyTopicServerTest {
 
         assertThat(respCaptor.getValue()).contains("111be3d2").doesNotContain("replaceMe");
     }
+
+    /**
+     * Tests process() when the message is a response.
+     */
+    @Test
+    public void testProcessNoResponse() {
+        // NOTE: this json file is a RESPONSE, not a request
+        String request = ResourceUtils.getResourceAsString("org/onap/policy/simulators/appc/appc.legacy.success.json");
+        assertNotNull(request);
+
+        server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, request);
+
+        verify(sink, never()).send(any());
+    }
 }
index 6e17642..11a5e3f 100644 (file)
@@ -85,6 +85,23 @@ public class TopicServerTest {
         verify(sink, never()).send(any());
     }
 
+    /**
+     * Tests onTopicEvent() when there is no response.
+     */
+    @Test
+    public void testOnTopicEventNoResponse() {
+        server = new MyServer() {
+            @Override
+            protected String process(MyRequest request) {
+                return null;
+            }
+        };
+
+        server.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, "{\"text\": \"bye-bye\"}");
+
+        verify(sink, never()).send(any());
+    }
+
 
     private class MyRequest {
         private String text;
index 8333800..a0b1655 100644 (file)
@@ -22,7 +22,9 @@ package org.onap.policy.models.simulators;
 
 import java.io.FileNotFoundException;
 import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicReference;
 import lombok.AccessLevel;
@@ -85,9 +87,8 @@ public class Main extends ServiceManagerContainer {
         AtomicReference<DmaapSimProvider> provRef = new AtomicReference<>();
         addAction(provName, () -> provRef.set(buildDmaapProvider(dmaapProv)), () -> provRef.get().shutdown());
 
-        // @formatter:off
-
         // REST server simulators
+        // @formatter:off
         for (ClassRestServerParameters restsim : params.getRestServers()) {
             AtomicReference<HttpServletServer> ref = new AtomicReference<>();
             addAction(restsim.getName(),
@@ -98,23 +99,30 @@ public class Main extends ServiceManagerContainer {
         // NOTE: topics must be started AFTER the (dmaap) rest servers
 
         // topic sinks
-        AtomicReference<List<TopicSink>> sinkRef = new AtomicReference<>();
-        addAction("topic sinks", () -> sinkRef.set(buildSinks(params.getTopicSinks())),
-            () -> shutdownSinks(sinkRef.get()));
+        Map<String, TopicSink> sinks = new HashMap<>();
+        for (TopicParameters topicParams : params.getTopicSinks()) {
+            String topic = topicParams.getTopic();
+            addAction("Sink " + topic,
+                () -> sinks.put(topic, startSink(topicParams)),
+                () -> sinks.get(topic).shutdown());
+        }
 
         // topic sources
-        AtomicReference<List<TopicSource>> sourceRef = new AtomicReference<>();
-        addAction("topic sources", () -> sourceRef.set(buildSources(params.getTopicSources())),
-            () -> shutdownSources(sourceRef.get()));
+        Map<String, TopicSource> sources = new HashMap<>();
+        for (TopicParameters topicParams : params.getTopicSources()) {
+            String topic = topicParams.getTopic();
+            addAction("Source " + topic,
+                () -> sources.put(topic, startSource(topicParams)),
+                () -> sources.get(topic).shutdown());
+        }
 
         // topic server simulators
         for (TopicServerParameters topicsim : params.getTopicServers()) {
             AtomicReference<TopicServer<?>> ref = new AtomicReference<>();
             addAction(topicsim.getName(),
-                () -> ref.set(buildTopicServer(topicsim, sinkRef.get(), sourceRef.get())),
+                () -> ref.set(buildTopicServer(topicsim, sinks, sources)),
                 () -> ref.get().shutdown());
         }
-
         // @formatter:on
     }
 
@@ -164,20 +172,16 @@ public class Main extends ServiceManagerContainer {
         return prov;
     }
 
-    protected List<TopicSink> buildSinks(List<TopicParameters> params) {
-        return TopicEndpointManager.getManager().addTopicSinks(params);
+    private TopicSink startSink(TopicParameters params) {
+        TopicSink sink = TopicEndpointManager.getManager().addTopicSinks(List.of(params)).get(0);
+        sink.start();
+        return sink;
     }
 
-    private void shutdownSinks(List<TopicSink> sinks) {
-        sinks.forEach(TopicSink::shutdown);
-    }
-
-    protected List<TopicSource> buildSources(List<TopicParameters> params) {
-        return TopicEndpointManager.getManager().addTopicSources(params);
-    }
-
-    private void shutdownSources(List<TopicSource> sources) {
-        sources.forEach(TopicSource::shutdown);
+    private TopicSource startSource(TopicParameters params) {
+        TopicSource source = TopicEndpointManager.getManager().addTopicSources(List.of(params)).get(0);
+        source.start();
+        return source;
     }
 
     private HttpServletServer buildRestServer(String dmaapName, ClassRestServerParameters params) {
@@ -201,17 +205,20 @@ public class Main extends ServiceManagerContainer {
         }
     }
 
-    private TopicServer<?> buildTopicServer(TopicServerParameters params, List<TopicSink> sinks,
-                    List<TopicSource> sources) {
+    private TopicServer<?> buildTopicServer(TopicServerParameters params, Map<String, TopicSink> sinks,
+                    Map<String, TopicSource> sources) {
         try {
             // find the desired sink
-            TopicSink sink = sinks.stream().filter(sink2 -> sink2.getTopic().equals(params.getSink())).findAny()
-                            .orElseThrow(() -> new IllegalArgumentException("invalid sink topic " + params.getSink()));
+            TopicSink sink = sinks.get(params.getSink());
+            if (sink == null) {
+                throw 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()));
+            TopicSource source = sources.get(params.getSource());
+            if (source == null) {
+                throw new IllegalArgumentException("invalid source topic " + params.getSource());
+            }
 
             // create the topic server
             return (TopicServer<?>) Class.forName(params.getProviderClass())
diff --git a/models-sim/policy-models-simulators/src/test/resources/appc.lcm.request.json b/models-sim/policy-models-simulators/src/test/resources/appc.lcm.request.json
new file mode 100644 (file)
index 0000000..cf2ebd5
--- /dev/null
@@ -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"
+}
index c7abb29..5f946f1 100644 (file)
@@ -58,7 +58,7 @@
             "useHttps": true
         },
         {
-            "topic": "APPC-LCM-READ",
+            "topic": "APPC-LCM-WRITE",
             "servers": ["localhost"],
             "topicCommInfrastructure": "DMAAP",
             "useHttps": true
@@ -72,7 +72,7 @@
             "useHttps": true
         },
         {
-            "topic": "APPC-LCM-WRITE",
+            "topic": "APPC-LCM-READ",
             "servers": ["localhost"],
             "topicCommInfrastructure": "DMAAP",
             "useHttps": true
@@ -88,8 +88,8 @@
         {
             "name": "APPC-LCM simulator",
             "providerClass": "org.onap.policy.simulators.AppcLcmTopicServer",
-            "sink": "APPC-LCM-READ",
-            "source": "APPC-LCM-WRITE"
+            "sink": "APPC-LCM-WRITE",
+            "source": "APPC-LCM-READ"
         }
     ]
 }