From 7f69c5ca0a6f6018166f8fee3e811edf4dee1eb8 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Thu, 20 Feb 2020 19:08:55 -0500 Subject: Change payload to Map so it's more versatile This was supposed to be two separate commits, but I goofed something. Added guard query to Operation superclass. Modified VfModuleCreate to store the VF count, pass it to the guard, and bump it once the create completes successfully. Added code to check Actors for proper plug-in to ActorService. Renamed "operation" property to "operations", to be more consistent with other parameters (e.g., TopicParameterGroup). The META-INF/services files for the actors had mixed case, which did not match the package name of the Actor class, preventing the ServiceLoader from recognizing them. Also modified the ActorService to skip any that cannot actually be loaded, for whatever reason (e.g., not in the classpath). Issue-ID: POLICY-1625 Signed-off-by: Jim Hahn Change-Id: Ifa97744543f2866cc553138ec5ec644b033de780 --- .../actor/appc/AppcActorServiceProvider.java | 2 +- .../controlloop/actor/appc/AppcOperation.java | 21 ++++++++++-- ...licy.controlloop.actorServiceProvider.spi.Actor | 1 - ...licy.controlloop.actorserviceprovider.spi.Actor | 1 + .../controlloop/actor/appc/AppcOperationTest.java | 32 +++++++++++++++++- .../actor/appc/AppcServiceProviderTest.java | 12 +++++-- .../controlloop/actor/appc/BasicAppcOperation.java | 3 +- .../actor/appc/ModifyConfigOperationTest.java | 19 ++++++++--- .../actor.appc/src/test/resources/service.yaml | 38 ++++++++++++++++++++++ 9 files changed, 115 insertions(+), 14 deletions(-) delete mode 100644 models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorServiceProvider.spi.Actor create mode 100644 models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorserviceprovider.spi.Actor create mode 100644 models-interactions/model-actors/actor.appc/src/test/resources/service.yaml (limited to 'models-interactions/model-actors/actor.appc/src') diff --git a/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcActorServiceProvider.java b/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcActorServiceProvider.java index f6a204540..76aa828c1 100644 --- a/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcActorServiceProvider.java +++ b/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcActorServiceProvider.java @@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory; public class AppcActorServiceProvider extends BidirectionalTopicActor { - private static final String NAME = "APPC"; + public static final String NAME = "APPC"; private static final Logger logger = LoggerFactory.getLogger(AppcActorServiceProvider.class); diff --git a/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcOperation.java b/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcOperation.java index 7d4af80ad..dc46f1253 100644 --- a/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcOperation.java +++ b/models-interactions/model-actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/AppcOperation.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import org.onap.policy.appc.CommonHeader; import org.onap.policy.appc.Request; import org.onap.policy.appc.Response; @@ -66,6 +67,14 @@ public abstract class AppcOperation extends BidirectionalTopicOperation startPreprocessorAsync() { + return startGuardAsync(); + } + /** * Makes a request, given the target VNF. This is a support function for * {@link #makeRequest(int)}. @@ -104,10 +113,16 @@ public abstract class AppcOperation extends BidirectionalTopicOperation source, Map target) { - for (Entry ent : source.entrySet()) { + private static void convertPayload(Map source, Map target) { + for (Entry ent : source.entrySet()) { + Object value = ent.getValue(); + if (value == null) { + target.put(ent.getKey(), null); + continue; + } + try { - target.put(ent.getKey(), coder.decode(ent.getValue(), Object.class)); + target.put(ent.getKey(), coder.decode(value.toString(), Object.class)); } catch (CoderException e) { logger.warn("cannot decode JSON value {}: {}", ent.getKey(), ent.getValue(), e); diff --git a/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorServiceProvider.spi.Actor b/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorServiceProvider.spi.Actor deleted file mode 100644 index f1002a301..000000000 --- a/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorServiceProvider.spi.Actor +++ /dev/null @@ -1 +0,0 @@ -org.onap.policy.controlloop.actor.appc.AppcActorServiceProvider \ No newline at end of file diff --git a/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorserviceprovider.spi.Actor b/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorserviceprovider.spi.Actor new file mode 100644 index 000000000..f1002a301 --- /dev/null +++ b/models-interactions/model-actors/actor.appc/src/main/resources/META-INF/services/org.onap.policy.controlloop.actorserviceprovider.spi.Actor @@ -0,0 +1 @@ +org.onap.policy.controlloop.actor.appc.AppcActorServiceProvider \ No newline at end of file diff --git a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcOperationTest.java b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcOperationTest.java index 218a4e532..8b71b614d 100644 --- a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcOperationTest.java +++ b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcOperationTest.java @@ -62,6 +62,11 @@ public class AppcOperationTest extends BasicAppcOperation { assertEquals(DEFAULT_OPERATION, oper.getName()); } + @Test + public void testStartPreprocessorAsync() { + assertNotNull(oper.startPreprocessorAsync()); + } + @Test public void testMakeRequest() { Request request = oper.makeRequest(2, MY_VNF); @@ -106,7 +111,7 @@ public class AppcOperationTest extends BasicAppcOperation { /* * insert invalid json text into the payload. */ - Map payload = new TreeMap<>(params.getPayload()); + Map payload = new TreeMap<>(params.getPayload()); payload.put("invalid-key", "{invalid json"); params = params.toBuilder().payload(payload).build(); @@ -126,6 +131,31 @@ public class AppcOperationTest extends BasicAppcOperation { KEY2, Map.of("output", "world")), request.getPayload()); // @formatter:on + + + /* + * insert null item into the payload. + */ + payload = new TreeMap<>(); + payload.put(KEY1, "abc"); + payload.put(KEY2, null); + payload.put(KEY3, "def"); + params = params.toBuilder().payload(payload).build(); + + oper = new AppcOperation(params, config) { + @Override + protected Request makeRequest(int attempt) { + return oper.makeRequest(attempt, MY_VNF); + } + }; + request = oper.makeRequest(2, MY_VNF); + + payload.put(AppcOperation.VNF_ID_KEY, MY_VNF); + payload.put(KEY1, "abc"); + payload.put(KEY2, null); + payload.put(KEY3, "def"); + + assertEquals(payload, request.getPayload()); } @Test diff --git a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java index 305c6d7cd..99e9d824a 100644 --- a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java +++ b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java @@ -43,6 +43,7 @@ import org.onap.policy.controlloop.ControlLoopEventStatus; import org.onap.policy.controlloop.ControlLoopOperation; import org.onap.policy.controlloop.ControlLoopTargetType; import org.onap.policy.controlloop.VirtualControlLoopEvent; +import org.onap.policy.controlloop.actor.test.BasicActor; import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.policy.Target; import org.onap.policy.controlloop.policy.TargetType; @@ -50,7 +51,7 @@ import org.onap.policy.simulators.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AppcServiceProviderTest { +public class AppcServiceProviderTest extends BasicActor { private static final String GENERIC_VNF_ID = "generic-vnf.vnf-id"; @@ -74,7 +75,8 @@ public class AppcServiceProviderTest { static { /* - * Construct an onset with an AAI subtag containing generic-vnf.vnf-id and a target type of VM. + * Construct an onset with an AAI subtag containing generic-vnf.vnf-id and a + * target type of VM. */ onsetEvent = new VirtualControlLoopEvent(); onsetEvent.setClosedLoopControlName("closedLoopControlName-Test"); @@ -139,6 +141,12 @@ public class AppcServiceProviderTest { assertEquals(expected.toString(), actual.toString()); } + @Test + public void testActorService() { + // verify that it all plugs into the ActorService + verifyActorService(AppcActorServiceProvider.NAME, "service.yaml"); + } + @Test public void testConstructModifyConfigRequest() { policy.setPayload(new HashMap<>()); diff --git a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/BasicAppcOperation.java b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/BasicAppcOperation.java index ed3e7a7ee..ecba91996 100644 --- a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/BasicAppcOperation.java +++ b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/BasicAppcOperation.java @@ -54,6 +54,7 @@ public abstract class BasicAppcOperation extends BasicBidirectionalTopicOperatio protected static final String MY_VNF = "my-vnf"; protected static final String KEY1 = "my-key-A"; protected static final String KEY2 = "my-key-B"; + protected static final String KEY3 = "my-key-C"; protected static final String VALUE1 = "{\"input\":\"hello\"}"; protected static final String VALUE2 = "{\"output\":\"world\"}"; protected static final String RESOURCE_ID = "my-resource"; @@ -162,7 +163,7 @@ public abstract class BasicAppcOperation extends BasicBidirectionalTopicOperatio } @Override - protected Map makePayload() { + protected Map makePayload() { return Map.of(KEY1, VALUE1, KEY2, VALUE2); } } diff --git a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/ModifyConfigOperationTest.java b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/ModifyConfigOperationTest.java index 5ff789715..460f2c9f0 100644 --- a/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/ModifyConfigOperationTest.java +++ b/models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/ModifyConfigOperationTest.java @@ -24,11 +24,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; @@ -42,6 +42,7 @@ import org.onap.policy.appc.Request; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; +import org.onap.policy.controlloop.policy.PolicyResult; public class ModifyConfigOperationTest extends BasicAppcOperation { @@ -64,10 +65,11 @@ public class ModifyConfigOperationTest extends BasicAppcOperation { } @Test - public void testStartPreprocessorAsync() { - CompletableFuture future = new CompletableFuture<>(); + public void testStartPreprocessorAsync() throws Exception { + CompletableFuture future2 = new CompletableFuture<>(); context = mock(ControlLoopEventContext.class); - when(context.obtain(eq(AaiCqResponse.CONTEXT_KEY), any())).thenReturn(future); + when(context.obtain(eq(AaiCqResponse.CONTEXT_KEY), any())).thenReturn(future2); + when(context.getEvent()).thenReturn(event); params = params.toBuilder().context(context).build(); AtomicBoolean guardStarted = new AtomicBoolean(); @@ -80,9 +82,16 @@ public class ModifyConfigOperationTest extends BasicAppcOperation { } }; - assertSame(future, oper.startPreprocessorAsync()); + CompletableFuture future3 = oper.startPreprocessorAsync(); + assertNotNull(future3); assertFalse(future.isDone()); assertTrue(guardStarted.get()); + verify(context).obtain(eq(AaiCqResponse.CONTEXT_KEY), any()); + + future2.complete(params.makeOutcome()); + assertTrue(executor.runAll(100)); + assertTrue(future3.isDone()); + assertEquals(PolicyResult.SUCCESS, future3.get().getResult()); } @Test diff --git a/models-interactions/model-actors/actor.appc/src/test/resources/service.yaml b/models-interactions/model-actors/actor.appc/src/test/resources/service.yaml new file mode 100644 index 000000000..ab9ad98b5 --- /dev/null +++ b/models-interactions/model-actors/actor.appc/src/test/resources/service.yaml @@ -0,0 +1,38 @@ +# +# ============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======================================================== +# +topics: + topicSources: + - topicCommInfrastructure: NOOP + topic: my-source + servers: + - localhost + managed: true + topicSinks: + - topicCommInfrastructure: NOOP + topic: my-sink + servers: + - localhost + managed: true +actors: + APPC: + sinkTopic: my-sink + sourceTopic: my-source + operations: + ModifyConfig: {} \ No newline at end of file -- cgit 1.2.3-korg