summaryrefslogtreecommitdiffstats
path: root/models-interactions/model-actors/actorServiceProvider/src/main
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/main
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/main')
-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
4 files changed, 26 insertions, 352 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);
}
}