From 19ef8b24a98c09a349e6ae7309f535a0135463f6 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 21 Aug 2020 13:43:08 -0400 Subject: Make Actors event-agnostic Removed event and event-context code from the Actor code. Also removed the preprocessing steps from the Actor code, giving the application complete control over any preprocessing. Also fixed a bug wherein the APPC actor was treating the AAI_RESOURCE_VNF property as a String instead of as a GenericVnf. Issue-ID: POLICY-2746-actor Change-Id: Ibc05fe39ffedc0bc461abf10e6a960861ac70119 Signed-off-by: Jim Hahn --- .../actorserviceprovider/OperationProperties.java | 2 +- .../controlloop/ControlLoopEventContext.java | 168 -------------------- .../impl/OperationPartial.java | 160 +++---------------- .../parameters/ControlLoopOperationParams.java | 48 +----- .../controlloop/ControlLoopEventContextTest.java | 151 ------------------ .../impl/HttpOperationTest.java | 10 +- .../impl/HttpOperatorTest.java | 9 +- .../impl/OperationPartialTest.java | 173 +-------------------- .../parameters/ControlLoopOperationParamsTest.java | 71 +-------- 9 files changed, 43 insertions(+), 749 deletions(-) delete mode 100644 models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContext.java delete mode 100644 models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContextTest.java (limited to 'models-interactions/model-actors/actorServiceProvider/src') diff --git a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/OperationProperties.java b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/OperationProperties.java index 718daedb1..d4dea7c48 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/OperationProperties.java +++ b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/OperationProperties.java @@ -54,7 +54,7 @@ public class OperationProperties { public static final String AAI_PNF = "AAI/pnf"; /** - * A&AI VNF id for the target resource ID. Obtained as follows: + * A&AI [Generic] VNF for the target resource ID. Obtained as follows: *
    *
  1. using the target resource ID, invoke the custom query * getGenericVnfByModelInvariantId() method to get the generic VNF
  2. diff --git a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContext.java b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContext.java deleted file mode 100644 index f7b58c11e..000000000 --- a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContext.java +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * ============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.controlloop.actorserviceprovider.controlloop; - -import java.io.Serializable; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NonNull; -import lombok.Setter; -import org.onap.policy.controlloop.VirtualControlLoopEvent; -import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; -import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; - -/** - * Context associated with a control loop event. - */ -@Getter -@Setter -public class ControlLoopEventContext implements Serializable { - private static final long serialVersionUID = 1L; - - - private final VirtualControlLoopEvent event; - - /** - * Enrichment data extracted from the event. Never {@code null}, though it may be - * immutable. - */ - private final Map enrichment; - - /** - * Set of properties that have been stored in the context. - */ - @Getter(AccessLevel.NONE) - @Setter(AccessLevel.NONE) - private Map properties = new ConcurrentHashMap<>(); - - /** - * When {@link #obtain(String, ControlLoopOperationParams)} is invoked and the - * specified property is not found in {@link #properties}, it is retrieved. This holds - * the futures for the operations retrieving the properties. - */ - @Getter(AccessLevel.NONE) - @Setter(AccessLevel.NONE) - private transient Map> retrievers = new ConcurrentHashMap<>(); - - /** - * Request ID extracted from the event, or a generated value if the event has no - * request id; never {@code null}. - */ - private final UUID requestId; - - - /** - * Constructs the object. - * - * @param event event with which this is associated - */ - public ControlLoopEventContext(@NonNull VirtualControlLoopEvent event) { - this.event = event; - this.requestId = (event.getRequestId() != null ? event.getRequestId() : UUID.randomUUID()); - this.enrichment = (event.getAai() != null ? event.getAai() : Map.of()); - } - - /** - * Determines if the context contains a property. - * - * @param name name of the property of interest - * @return {@code true} if the context contains the property, {@code false} otherwise - */ - public boolean contains(String name) { - return properties.containsKey(name); - } - - /** - * Gets a property, casting it to the desired type. - * - * @param desired type - * @param name name of the property whose value is to be retrieved - * @return the property's value, or {@code null} if it does not yet have a value - */ - @SuppressWarnings("unchecked") - public T getProperty(String name) { - return (T) properties.get(name); - } - - /** - * Sets a property's value. - * - * @param name property name - * @param value new property value - */ - public void setProperty(String name, Serializable value) { - properties.put(name, value); - } - - /** - * Removes a property. - * @param name property name - */ - public void removeProperty(String name) { - properties.remove(name); - } - - /** - * Obtains the given property. - * - * @param name name of the desired property - * @param params parameters needed to perform the operation to retrieve the desired - * property - * @return a future for retrieving the property, {@code null} if the property has - * already been retrieved - */ - public CompletableFuture obtain(String name, ControlLoopOperationParams params) { - if (properties.containsKey(name)) { - return null; - } - - /* - * Return any existing future, if it wasn't canceled. Otherwise, start a new - * request. - */ - - // @formatter:off - CompletableFuture oldFuture = - retrievers.computeIfPresent(name, (key, future) -> future.isCancelled() ? null : future); - // @formatter:on - - if (oldFuture != null) { - return oldFuture; - } - - /* - * Note: must NOT invoke params.start() within retrievers.compute(), as start() - * may invoke obtain() which would cause a recursive update to the retrievers map. - */ - CompletableFuture future = params.start(); - - if ((oldFuture = retrievers.putIfAbsent(name, future)) != null) { - future.cancel(false); - return oldFuture; - } - - return future; - } -} diff --git a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartial.java b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartial.java index c81575f62..e9f6b024c 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartial.java +++ b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartial.java @@ -24,7 +24,6 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -65,9 +64,7 @@ import org.slf4j.LoggerFactory; * Partial implementation of an operator. In general, it's preferable that subclasses * would override {@link #startOperationAsync(int, OperationOutcome) * startOperationAsync()}. However, if that proves to be too difficult, then they can - * simply override {@link #doOperation(int, OperationOutcome) doOperation()}. In addition, - * if the operation requires any preprocessor steps, the subclass may choose to override - * {@link #startPreprocessorAsync()}. + * simply override {@link #doOperation(int, OperationOutcome) doOperation()}. *

    * The futures returned by the methods within this class can be canceled, and will * propagate the cancellation to any subtasks. Thus it is also expected that any futures @@ -159,153 +156,36 @@ public abstract class OperationPartial implements Operation { return (T) properties.get(name); } - @Override - public CompletableFuture start() { - // allocate a controller for the entire operation - final PipelineControllerFuture controller = new PipelineControllerFuture<>(); - - CompletableFuture preproc = startPreprocessorAsync(); - if (preproc == null) { - // no preprocessor required - just start the operation - return startOperationAttempt(controller, 1); - } - - /* - * Do preprocessor first and then, if successful, start the operation. Note: - * operations create their own outcome, ignoring the outcome from any previous - * steps. - * - * Wrap the preprocessor to ensure "stop" is propagated to it. - */ - // @formatter:off - controller.wrap(preproc) - .exceptionally(fromException("preprocessor of operation")) - .thenCompose(handlePreprocessorFailure(controller)) - .thenCompose(unusedOutcome -> startOperationAttempt(controller, 1)) - .whenCompleteAsync(controller.delayedComplete(), params.getExecutor()); - // @formatter:on - - return controller; - } - /** - * Handles a failure in the preprocessor pipeline. If a failure occurred, then it - * invokes the call-backs, marks the controller complete, and returns an incomplete - * future, effectively halting the pipeline. Otherwise, it returns the outcome that it - * received. - *

    - * Assumes that no callbacks have been invoked yet. + * Gets a property value, throwing an exception if it's missing. * - * @param controller pipeline controller - * @return a function that checks the outcome status and continues, if successful, or - * indicates a failure otherwise + * @param name property name + * @param propertyType property type, used in an error message if the property value + * is {@code null} + * @return the property value */ - private Function> handlePreprocessorFailure( - PipelineControllerFuture controller) { - - return outcome -> { - - if (isSuccess(outcome)) { - logger.info("{}: preprocessor succeeded for {}", getFullName(), params.getRequestId()); - return CompletableFuture.completedFuture(outcome); - } - - logger.warn("preprocessor failed, discontinuing operation {} for {}", getFullName(), params.getRequestId()); - - final Executor executor = params.getExecutor(); - final CallbackManager callbacks = new CallbackManager(); - - // propagate "stop" to the callbacks - controller.add(callbacks); - - final OperationOutcome outcome2 = params.makeOutcome(getTargetEntity()); - - // TODO need a FAILURE_MISSING_DATA (e.g., A&AI) - - outcome2.setFinalOutcome(true); - outcome2.setResult(OperationResult.FAILURE_GUARD); - outcome2.setMessage(outcome != null ? outcome.getMessage() : null); - - // @formatter:off - CompletableFuture.completedFuture(outcome2) - .whenCompleteAsync(callbackStarted(callbacks), executor) - .whenCompleteAsync(callbackCompleted(callbacks), executor) - .whenCompleteAsync(controller.delayedComplete(), executor); - // @formatter:on - - return new CompletableFuture<>(); - }; - } - - /** - * Invokes the operation's preprocessor step(s) as a "future". This method simply - * returns {@code null}. - *

    - * This method assumes the following: - *

      - *
    • the operator is alive
    • - *
    • exceptions generated within the pipeline will be handled by the invoker
    • - *
    - * - * @return a function that will start the preprocessor and returns its outcome, or - * {@code null} if this operation needs no preprocessor - */ - protected CompletableFuture startPreprocessorAsync() { - return null; - } - - /** - * Invokes the operation's guard step(s) as a "future". - *

    - * This method assumes the following: - *

      - *
    • the operator is alive
    • - *
    • exceptions generated within the pipeline will be handled by the invoker
    • - *
    - * - * @return a function that will start the guard checks and returns its outcome, or - * {@code null} if this operation has no guard - */ - protected CompletableFuture startGuardAsync() { - if (params.isPreprocessed()) { - return null; + @SuppressWarnings("unchecked") + protected T getRequiredProperty(String name, String propertyType) { + T value = (T) properties.get(name); + if (value == null) { + throw new IllegalStateException("missing " + propertyType); } - // get the guard payload - Map payload = makeGuardPayload(); - - /* - * Note: can't use constants from actor.guard, because that would create a - * circular dependency. - */ - return params.toBuilder().actor(GUARD_ACTOR_NAME).operation(GUARD_OPERATION_NAME).retry(null).timeoutSec(null) - .payload(payload).build().start(); + return value; } - /** - * Creates a payload to execute a guard operation. - * - * @return a new guard payload - */ - protected Map makeGuardPayload() { - // TODO delete this once preprocessing is done by the application - Map guard = new LinkedHashMap<>(); - guard.put("actor", params.getActor()); - guard.put("operation", params.getOperation()); - guard.put("target", getTargetEntity()); - guard.put("requestId", params.getRequestId()); - - String clname = params.getContext().getEvent().getClosedLoopControlName(); - if (clname != null) { - guard.put("clname", clname); - } + @Override + public CompletableFuture start() { + // allocate a controller for the entire operation + final PipelineControllerFuture controller = new PipelineControllerFuture<>(); - return guard; + // start attempt #1 + return startOperationAttempt(controller, 1); } /** - * Starts the operation attempt, with no preprocessor. When all retries complete, it - * will complete the controller. + * Starts the operation attempt. When all retries complete, it will complete the + * controller. * * @param controller controller for all operation attempts * @param attempt attempt number, typically starting with 1 diff --git a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParams.java b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParams.java index 0e4f09b66..67f68036b 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParams.java +++ b/models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParams.java @@ -33,13 +33,11 @@ import lombok.Getter; 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.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.ActorService; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.TargetType; import org.onap.policy.controlloop.actorserviceprovider.Util; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,14 +72,10 @@ public class ControlLoopOperationParams { private ActorService actorService; /** - * Event for which the operation applies. - */ - // TODO to be removed - private ControlLoopEventContext context; - - /** - * If {@code null}, this value is extracted from the context. + * Request ID with which all actor operations are associated. Used to track requests + * across various components/servers. */ + @NotNull private UUID requestId; /** @@ -106,6 +100,7 @@ public class ControlLoopOperationParams { * {@code True} if the preprocessing steps have already been executed, {@code false} * otherwise. */ + // TODO remove this once the rules no longer reference it private boolean preprocessed; /** @@ -194,11 +189,6 @@ public class ControlLoopOperationParams { * @return the event's request ID, or {@code null} if no request ID is available */ public UUID getRequestId() { - if (requestId == null && context != null && context.getEvent() != null) { - // cache the request ID - requestId = context.getEvent().getRequestId(); - } - return requestId; } @@ -266,34 +256,6 @@ public class ControlLoopOperationParams { * @return the validation result */ public BeanValidationResult validate() { - BeanValidationResult result = - new BeanValidator().validateTop(ControlLoopOperationParams.class.getSimpleName(), this); - - // validate that we have a request ID, or that we can get it from the context's - // event - - if (context == null) { - // no context specified - invoker must provide a request ID then - result.validateNotNull("requestId", requestId); - - } else if (requestId == null) { - // have a context, but no request ID - check the context's event for the - // request ID - BeanValidationResult contextResult = new BeanValidationResult("context", context); - VirtualControlLoopEvent event = context.getEvent(); - contextResult.validateNotNull("event", event); - - if (event != null) { - // cache the request id for later use - BeanValidationResult eventResult = new BeanValidationResult("event", event); - eventResult.validateNotNull("requestId", event.getRequestId()); - - contextResult.addResult(eventResult); - } - - result.addResult(contextResult); - } - - return result; + return new BeanValidator().validateTop(ControlLoopOperationParams.class.getSimpleName(), this); } } diff --git a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContextTest.java b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContextTest.java deleted file mode 100644 index 0f44f4f36..000000000 --- a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContextTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.controlloop.actorserviceprovider.controlloop; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import org.junit.Before; -import org.junit.Test; -import org.onap.policy.controlloop.VirtualControlLoopEvent; -import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; -import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; - -public class ControlLoopEventContextTest { - private static final String MY_KEY = "def"; - private static final UUID REQ_ID = UUID.randomUUID(); - private static final String ITEM_KEY = "obtain-C"; - - private Map enrichment; - private VirtualControlLoopEvent event; - private ControlLoopEventContext context; - - /** - * Initializes data, including {@link #context}. - */ - @Before - public void setUp() { - enrichment = Map.of("abc", "one", MY_KEY, "two"); - - event = new VirtualControlLoopEvent(); - event.setRequestId(REQ_ID); - event.setAai(enrichment); - - context = new ControlLoopEventContext(event); - } - - @Test - public void testControlLoopEventContext() { - assertSame(event, context.getEvent()); - assertSame(REQ_ID, context.getRequestId()); - assertEquals(enrichment, context.getEnrichment()); - - // null event - assertThatThrownBy(() -> new ControlLoopEventContext(null)); - - // no request id, no enrichment data - event.setRequestId(null); - event.setAai(null); - context = new ControlLoopEventContext(event); - assertSame(event, context.getEvent()); - assertNotNull(context.getRequestId()); - assertEquals(Map.of(), context.getEnrichment()); - } - - @Test - public void testContains_testGetProperty_testSetProperty_testRemoveProperty() { - context.setProperty("abc", "a string"); - context.setProperty(MY_KEY, 100); - - assertTrue(context.contains(MY_KEY)); - assertFalse(context.contains("ghi")); - - String strValue = context.getProperty("abc"); - assertEquals("a string", strValue); - - int intValue = context.getProperty(MY_KEY); - assertEquals(100, intValue); - - context.removeProperty(MY_KEY); - assertFalse(context.contains(MY_KEY)); - } - - @Test - public void testObtain() { - final ControlLoopOperationParams params = mock(ControlLoopOperationParams.class); - - // property is already loaded - context.setProperty("obtain-A", "value-A"); - assertNull(context.obtain("obtain-A", params)); - - // new property - should retrieve - CompletableFuture future = new CompletableFuture<>(); - when(params.start()).thenReturn(future); - assertSame(future, context.obtain("obtain-B", params)); - - // repeat - should get the same future, without invoking start() again - assertSame(future, context.obtain("obtain-B", params)); - verify(params).start(); - - // arrange for another invoker to start while this one is starting - CompletableFuture future2 = new CompletableFuture<>(); - - when(params.start()).thenAnswer(args -> { - - ControlLoopOperationParams params2 = mock(ControlLoopOperationParams.class); - when(params2.start()).thenReturn(future2); - - assertSame(future2, context.obtain(ITEM_KEY, params2)); - return future; - }); - - assertSame(future2, context.obtain(ITEM_KEY, params)); - - // should have canceled the interrupted future - assertTrue(future.isCancelled()); - - // return a new future next time start() is called - CompletableFuture future3 = new CompletableFuture<>(); - when(params.start()).thenReturn(future3); - - // repeat - should get the same future - assertSame(future2, context.obtain(ITEM_KEY, params)); - assertSame(future2, context.obtain(ITEM_KEY, params)); - - // future2 should still be active - assertFalse(future2.isCancelled()); - - // cancel it - now we should get the new future - future2.cancel(false); - assertSame(future3, context.obtain(ITEM_KEY, params)); - } -} diff --git a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperationTest.java b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperationTest.java index 453592d2b..587313a46 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperationTest.java +++ b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperationTest.java @@ -77,10 +77,8 @@ import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; import org.onap.policy.common.gson.GsonMessageBodyHandler; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.network.NetworkUtil; -import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.OperationResult; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig; import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams; @@ -118,8 +116,6 @@ public class HttpOperationTest { @Mock private Executor executor; - private VirtualControlLoopEvent event; - private ControlLoopEventContext context; private ControlLoopOperationParams params; private OperationOutcome outcome; private AtomicReference> callback; @@ -184,11 +180,7 @@ public class HttpOperationTest { when(response.readEntity(String.class)).thenReturn(TEXT); when(response.getStatus()).thenReturn(200); - event = new VirtualControlLoopEvent(); - event.setRequestId(REQ_ID); - - context = new ControlLoopEventContext(event); - params = ControlLoopOperationParams.builder().actor(ACTOR).operation(OPERATION).context(context).build(); + params = ControlLoopOperationParams.builder().actor(ACTOR).operation(OPERATION).requestId(REQ_ID).build(); outcome = params.makeOutcome(null); diff --git a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperatorTest.java b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperatorTest.java index 5ae804aea..af8f1aaab 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperatorTest.java +++ b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperatorTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import java.util.Collections; import java.util.Map; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import org.junit.Before; import org.junit.Test; @@ -37,11 +38,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.policy.common.endpoints.http.client.HttpClient; import org.onap.policy.common.endpoints.http.client.HttpClientFactory; -import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.Util; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig; import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams; @@ -112,10 +111,8 @@ public class HttpOperatorTest { assertNotNull(oper2); assertNotNull(oper2.getClientFactory()); - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - ControlLoopEventContext context = new ControlLoopEventContext(event); - ControlLoopOperationParams params = - ControlLoopOperationParams.builder().actor(ACTOR).operation(OPERATION).context(context).build(); + ControlLoopOperationParams params = ControlLoopOperationParams.builder().actor(ACTOR).operation(OPERATION) + .requestId(UUID.randomUUID()).build(); // configure and start it HttpParams params2 = HttpParams.builder().clientName(HTTP_CLIENT).path(PATH).timeoutSec(TIMEOUT).build(); diff --git a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartialTest.java b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartialTest.java index 455393c93..b7a6a1d3b 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartialTest.java +++ b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartialTest.java @@ -29,7 +29,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import ch.qos.logback.classic.Logger; @@ -60,7 +59,6 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; 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; @@ -71,14 +69,12 @@ import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.test.log.logback.ExtractAppender; import org.onap.policy.common.utils.time.PseudoExecutor; import org.onap.policy.controlloop.ControlLoopOperation; -import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.ActorService; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.OperationProperties; import org.onap.policy.controlloop.actorserviceprovider.OperationResult; import org.onap.policy.controlloop.actorserviceprovider.Operator; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; import org.onap.policy.controlloop.actorserviceprovider.parameters.OperatorConfig; import org.onap.policy.controlloop.actorserviceprovider.spi.Actor; @@ -119,8 +115,6 @@ public class OperationPartialTest { @Mock private Operation guardOperation; - private VirtualControlLoopEvent event; - private ControlLoopEventContext context; private PseudoExecutor executor; private ControlLoopOperationParams params; @@ -167,14 +161,9 @@ public class OperationPartialTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - - event = new VirtualControlLoopEvent(); - event.setRequestId(REQ_ID); - - context = new ControlLoopEventContext(event); executor = new PseudoExecutor(); - params = ControlLoopOperationParams.builder().completeCallback(this::completer).context(context) + params = ControlLoopOperationParams.builder().completeCallback(this::completer).requestId(REQ_ID) .executor(executor).actorService(service).actor(ACTOR).operation(OPERATION).timeoutSec(TIMEOUT) .startCallback(this::starter).targetEntity(MY_TARGET_ENTITY).build(); @@ -226,14 +215,20 @@ public class OperationPartialTest { } @Test - public void testGetProperty_testSetProperty() { + public void testGetProperty_testSetProperty_testGetRequiredProperty() { oper.setProperty("propertyA", "valueA"); oper.setProperty("propertyB", "valueB"); oper.setProperty("propertyC", 20); + oper.setProperty("propertyD", "valueD"); assertEquals("valueA", oper.getProperty("propertyA")); assertEquals("valueB", oper.getProperty("propertyB")); assertEquals(Integer.valueOf(20), oper.getProperty("propertyC")); + + assertEquals("valueD", oper.getRequiredProperty("propertyD", "typeD")); + + assertThatIllegalStateException().isThrownBy(() -> oper.getRequiredProperty("propertyUnknown", "some type")) + .withMessage("missing some type"); } @Test @@ -261,118 +256,6 @@ public class OperationPartialTest { assertEquals(MAX_PARALLEL, numEnd); } - /** - * Tests startPreprocessor() when the preprocessor returns a failure. - */ - @Test - public void testStartPreprocessorFailure() { - oper.setPreProc(CompletableFuture.completedFuture(makeFailure())); - - verifyRun("testStartPreprocessorFailure", 1, 0, OperationResult.FAILURE_GUARD); - } - - /** - * Tests startPreprocessor() when the preprocessor throws an exception. - */ - @Test - public void testStartPreprocessorException() { - // arrange for the preprocessor to throw an exception - oper.setPreProc(CompletableFuture.failedFuture(new IllegalStateException(EXPECTED_EXCEPTION))); - - verifyRun("testStartPreprocessorException", 1, 0, OperationResult.FAILURE_GUARD); - } - - /** - * Tests startPreprocessor() when the pipeline is not running. - */ - @Test - public void testStartPreprocessorNotRunning() { - // arrange for the preprocessor to return success, which will be ignored - // oper.setGuard(CompletableFuture.completedFuture(makeSuccess())); - - oper.start().cancel(false); - assertTrue(executor.runAll(MAX_REQUESTS)); - - assertNull(opstart); - assertNull(opend); - - assertEquals(0, numStart); - assertEquals(0, oper.getCount()); - assertEquals(0, numEnd); - } - - /** - * Tests startPreprocessor() when the preprocessor builder throws an exception. - */ - @Test - public void testStartPreprocessorBuilderException() { - oper = new MyOper() { - @Override - protected CompletableFuture startPreprocessorAsync() { - throw new IllegalStateException(EXPECTED_EXCEPTION); - } - }; - - assertThatIllegalStateException().isThrownBy(() -> oper.start()); - - // should be nothing in the queue - assertEquals(0, executor.getQueueLength()); - } - - @Test - public void testStartPreprocessorAsync() { - assertNull(oper.startPreprocessorAsync()); - } - - @Test - public void testStartGuardAsync() throws Exception { - CompletableFuture future = oper.startGuardAsync(); - assertTrue(future.isDone()); - assertEquals(OperationResult.SUCCESS, future.get().getResult()); - - // verify the parameters that were passed - ArgumentCaptor paramsCaptor = - ArgumentCaptor.forClass(ControlLoopOperationParams.class); - verify(guardOperator).buildOperation(paramsCaptor.capture()); - - params = paramsCaptor.getValue(); - assertEquals(OperationPartial.GUARD_ACTOR_NAME, params.getActor()); - assertEquals(OperationPartial.GUARD_OPERATION_NAME, params.getOperation()); - assertNull(params.getRetry()); - assertNull(params.getTimeoutSec()); - - Map payload = params.getPayload(); - assertNotNull(payload); - - assertEquals(oper.makeGuardPayload(), payload); - } - - /** - * Tests startGuardAsync() when preprocessing is disabled. - */ - @Test - public void testStartGuardAsyncDisabled() { - params = params.toBuilder().preprocessed(true).build(); - assertNull(new MyOper().startGuardAsync()); - } - - @Test - public void testMakeGuardPayload() { - Map payload = oper.makeGuardPayload(); - assertSame(REQ_ID, payload.get("requestId")); - - // request id changes, so remove it - payload.remove("requestId"); - - assertEquals("{actor=my-actor, operation=my-operation, target=my-entity}", payload.toString()); - - // repeat, but with closed loop name - event.setClosedLoopControlName("my-loop"); - payload = oper.makeGuardPayload(); - payload.remove("requestId"); - assertEquals("{actor=my-actor, operation=my-operation, target=my-entity, clname=my-loop}", payload.toString()); - } - @Test public void testStartOperationAsync() { oper.start(); @@ -616,34 +499,6 @@ public class OperationPartialTest { assertTrue(oper.isSameOperation(outcome)); } - /** - * Tests handleFailure() when the outcome is a success. - */ - @Test - public void testHandlePreprocessorFailureSuccess() { - oper.setPreProc(CompletableFuture.completedFuture(makeSuccess())); - verifyRun("testHandlePreprocessorFailureTrue", 1, 1, OperationResult.SUCCESS); - } - - /** - * Tests handleFailure() when the outcome is not a success. - */ - @Test - public void testHandlePreprocessorFailureFailed() throws Exception { - oper.setPreProc(CompletableFuture.completedFuture(makeFailure())); - verifyRun("testHandlePreprocessorFailureFalse", 1, 0, OperationResult.FAILURE_GUARD); - } - - /** - * Tests handleFailure() when the outcome is {@code null}. - */ - @Test - public void testHandlePreprocessorFailureNull() throws Exception { - // arrange to return a null outcome from the preprocessor - oper.setPreProc(CompletableFuture.completedFuture(null)); - verifyRun("testHandlePreprocessorFailureNull", 1, 0, OperationResult.FAILURE_GUARD); - } - @Test public void testFromException() { // arrange to generate an exception when operation runs @@ -1204,13 +1059,6 @@ public class OperationPartialTest { return outcome; } - private OperationOutcome makeFailure() { - OperationOutcome outcome = params.makeOutcome(null); - outcome.setResult(OperationResult.FAILURE); - - return outcome; - } - /** * Verifies a run. * @@ -1358,10 +1206,5 @@ public class OperationPartialTest { */ return 0L; } - - @Override - protected CompletableFuture startPreprocessorAsync() { - return (preProc != null ? preProc : super.startPreprocessorAsync()); - } } } diff --git a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParamsTest.java b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParamsTest.java index caa840891..b6bd50c7e 100644 --- a/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParamsTest.java +++ b/models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParamsTest.java @@ -49,18 +49,15 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.ActorService; import org.onap.policy.controlloop.actorserviceprovider.Operation; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; import org.onap.policy.controlloop.actorserviceprovider.Operator; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams.ControlLoopOperationParamsBuilder; import org.onap.policy.controlloop.actorserviceprovider.spi.Actor; public class ControlLoopOperationParamsTest { private static final String NULL_MSG = "null"; - private static final String REQUEST_ID_NAME = "requestId"; private static final String EXPECTED_EXCEPTION = "expected exception"; private static final String ACTOR = "my-actor"; private static final String OPERATION = "my-operation"; @@ -68,7 +65,6 @@ public class ControlLoopOperationParamsTest { private static final Integer RETRY = 3; private static final Integer TIMEOUT = 100; private static final UUID REQ_ID = UUID.randomUUID(); - private static final UUID REQ_ID2 = UUID.randomUUID(); @Mock private Actor actor; @@ -79,12 +75,6 @@ public class ControlLoopOperationParamsTest { @Mock private Consumer completer; - @Mock - private ControlLoopEventContext context; - - @Mock - private VirtualControlLoopEvent event; - @Mock private Executor executor; @@ -118,14 +108,10 @@ public class ControlLoopOperationParamsTest { when(operator.buildOperation(any())).thenReturn(operation); when(operation.start()).thenReturn(operFuture); - when(event.getRequestId()).thenReturn(REQ_ID); - - when(context.getEvent()).thenReturn(event); - payload = new TreeMap<>(); params = ControlLoopOperationParams.builder().actorService(actorService).completeCallback(completer) - .context(context).executor(executor).actor(ACTOR).operation(OPERATION).payload(payload) + .requestId(REQ_ID).executor(executor).actor(ACTOR).operation(OPERATION).payload(payload) .retry(RETRY).targetEntity(TARGET_ENTITY).timeoutSec(TIMEOUT) .startCallback(starter).preprocessed(true).build(); @@ -134,14 +120,14 @@ public class ControlLoopOperationParamsTest { @Test public void testStart() { - assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().context(null).build().start()); + assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().requestId(null).build().start()); assertSame(operFuture, params.start()); } @Test public void testBuild() { - assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().context(null).build().build()); + assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().requestId(null).build().build()); assertSame(operation, params.build()); } @@ -149,26 +135,6 @@ public class ControlLoopOperationParamsTest { @Test public void testGetRequestId() { assertSame(REQ_ID, params.getRequestId()); - - // when both request ID and event request ID are set - should use request ID - // parameter - assertSame(REQ_ID2, params.toBuilder().requestId(REQ_ID2).build().getRequestId()); - } - - /** - * Tests getRequestId() when the request ID is not available in the context. - */ - @Test - public void testGetRequestIdNotFromContext() { - // try with null context - assertNull(params.toBuilder().context(null).build().getRequestId()); - - // try with null event - when(context.getEvent()).thenReturn(null); - assertNull(params.getRequestId()); - - // set request ID directly - assertSame(REQ_ID2, params.toBuilder().requestId(REQ_ID2).build().getRequestId()); } @Test @@ -243,14 +209,12 @@ public class ControlLoopOperationParamsTest { testValidate("actorService", NULL_MSG, bldr -> bldr.actorService(null)); testValidate("executor", NULL_MSG, bldr -> bldr.executor(null)); testValidate("operation", NULL_MSG, bldr -> bldr.operation(null)); + testValidate("requestId", NULL_MSG, bldr -> bldr.requestId(null)); // has no target entity BeanValidationResult result = params.toBuilder().targetEntity(null).build().validate(); assertTrue(result.isValid()); - // note: if context is null, then it will ACTUALLY complain about the request ID - testValidate(REQUEST_ID_NAME, NULL_MSG, bldr -> bldr.context(null)); - // check edge cases assertTrue(params.toBuilder().build().validate().isValid()); @@ -259,28 +223,8 @@ public class ControlLoopOperationParamsTest { .completeCallback(null).build().validate().isValid()); // test with minimal fields - assertTrue(ControlLoopOperationParams.builder().actorService(actorService).context(context).actor(ACTOR) + assertTrue(ControlLoopOperationParams.builder().actorService(actorService).requestId(REQ_ID).actor(ACTOR) .operation(OPERATION).targetEntity(TARGET_ENTITY).build().validate().isValid()); - - // test when event has no request ID - when(event.getRequestId()).thenReturn(null); - result = params.validate(); - assertFalse(result.isValid()); - assertThat(result.getResult()).contains("event").contains(REQUEST_ID_NAME).contains(NULL_MSG); - - // try when context has no event - when(context.getEvent()).thenReturn(null); - result = params.validate(); - assertFalse(result.isValid()); - assertThat(result.getResult()).contains("event").doesNotContain(REQUEST_ID_NAME).contains(NULL_MSG); - - // has both request ID and context, but no event - result = params.toBuilder().requestId(REQ_ID2).build().validate(); - assertTrue(result.isValid()); - - // has request ID, but not context - result = params.toBuilder().requestId(REQ_ID2).context(null).build().validate(); - assertTrue(result.isValid()); } private void testValidate(String fieldName, String expected, @@ -311,11 +255,6 @@ public class ControlLoopOperationParamsTest { assertSame(actorService, params.getActorService()); } - @Test - public void testGetContext() { - assertSame(context, params.getContext()); - } - @Test public void testGetExecutor() { assertSame(executor, params.getExecutor()); -- cgit 1.2.3-korg