summaryrefslogtreecommitdiffstats
path: root/models-interactions/model-actors/actorServiceProvider/src
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2020-08-21 13:43:08 -0400
committerJim Hahn <jrh3@att.com>2020-10-27 14:55:15 -0400
commit19ef8b24a98c09a349e6ae7309f535a0135463f6 (patch)
treed988e5a58865ae6f3a38dcb31e4f195f18e59946 /models-interactions/model-actors/actorServiceProvider/src
parent6b29d2c19e288148171db0c0e446e18dcd46effd (diff)
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 <jrh3@att.com>
Diffstat (limited to 'models-interactions/model-actors/actorServiceProvider/src')
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/OperationProperties.java2
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContext.java168
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartial.java160
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/main/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParams.java48
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/controlloop/ControlLoopEventContextTest.java151
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperationTest.java10
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/HttpOperatorTest.java9
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/impl/OperationPartialTest.java173
-rw-r--r--models-interactions/model-actors/actorServiceProvider/src/test/java/org/onap/policy/controlloop/actorserviceprovider/parameters/ControlLoopOperationParamsTest.java71
9 files changed, 43 insertions, 749 deletions
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:
* <ol>
* <li>using the target resource ID, invoke the custom query
* getGenericVnfByModelInvariantId() method to get the generic VNF</li>
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<String, String> enrichment;
-
- /**
- * Set of properties that have been stored in the context.
- */
- @Getter(AccessLevel.NONE)
- @Setter(AccessLevel.NONE)
- private Map<String, Serializable> 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<String, CompletableFuture<OperationOutcome>> 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 <T> 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> 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<OperationOutcome> 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<OperationOutcome> 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<OperationOutcome> 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()}.
* <p/>
* 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<OperationOutcome> start() {
- // allocate a controller for the entire operation
- final PipelineControllerFuture<OperationOutcome> controller = new PipelineControllerFuture<>();
-
- CompletableFuture<OperationOutcome> 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.
- * <p/>
- * 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<OperationOutcome, CompletableFuture<OperationOutcome>> handlePreprocessorFailure(
- PipelineControllerFuture<OperationOutcome> 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}.
- * <p/>
- * This method assumes the following:
- * <ul>
- * <li>the operator is alive</li>
- * <li>exceptions generated within the pipeline will be handled by the invoker</li>
- * </ul>
- *
- * @return a function that will start the preprocessor and returns its outcome, or
- * {@code null} if this operation needs no preprocessor
- */
- protected CompletableFuture<OperationOutcome> startPreprocessorAsync() {
- return null;
- }
-
- /**
- * Invokes the operation's guard step(s) as a "future".
- * <p/>
- * This method assumes the following:
- * <ul>
- * <li>the operator is alive</li>
- * <li>exceptions generated within the pipeline will be handled by the invoker</li>
- * </ul>
- *
- * @return a function that will start the guard checks and returns its outcome, or
- * {@code null} if this operation has no guard
- */
- protected CompletableFuture<OperationOutcome> startGuardAsync() {
- if (params.isPreprocessed()) {
- return null;
+ @SuppressWarnings("unchecked")
+ protected <T> 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<String, Object> 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<String, Object> makeGuardPayload() {
- // TODO delete this once preprocessing is done by the application
- Map<String, Object> 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<OperationOutcome> start() {
+ // allocate a controller for the entire operation
+ final PipelineControllerFuture<OperationOutcome> 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<String, String> 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<OperationOutcome> 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<OperationOutcome> 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<OperationOutcome> 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<InvocationCallback<Response>> 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 <b>builder</b> throws an exception.
- */
- @Test
- public void testStartPreprocessorBuilderException() {
- oper = new MyOper() {
- @Override
- protected CompletableFuture<OperationOutcome> 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<OperationOutcome> future = oper.startGuardAsync();
- assertTrue(future.isDone());
- assertEquals(OperationResult.SUCCESS, future.get().getResult());
-
- // verify the parameters that were passed
- ArgumentCaptor<ControlLoopOperationParams> 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<String, Object> 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<String, Object> 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 <i>not</i> 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<OperationOutcome> 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;
@@ -80,12 +76,6 @@ public class ControlLoopOperationParamsTest {
private Consumer<OperationOutcome> completer;
@Mock
- private ControlLoopEventContext context;
-
- @Mock
- private VirtualControlLoopEvent event;
-
- @Mock
private Executor executor;
@Mock
@@ -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,
@@ -312,11 +256,6 @@ public class ControlLoopOperationParamsTest {
}
@Test
- public void testGetContext() {
- assertSame(context, params.getContext());
- }
-
- @Test
public void testGetExecutor() {
assertSame(executor, params.getExecutor());