Modify Actors to use properties when provided
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / main / java / org / onap / policy / controlloop / actorserviceprovider / impl / OperationPartial.java
index 4aa7236..0aa1122 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.policy.controlloop.actorserviceprovider.impl;
 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;
@@ -103,17 +104,27 @@ public abstract class OperationPartial implements Operation {
     @Setter(AccessLevel.PROTECTED)
     private String subRequestId;
 
+    @Getter
+    private final List<String> propertyNames;
+
+    /**
+     * Values for the properties identified by {@link #getPropertyNames()}.
+     */
+    private final Map<String, Object> properties = new HashMap<>();
+
 
     /**
      * Constructs the object.
      *
      * @param params operation parameters
      * @param config configuration for this operation
+     * @param propertyNames names of properties required by this operation
      */
-    public OperationPartial(ControlLoopOperationParams params, OperatorConfig config) {
+    public OperationPartial(ControlLoopOperationParams params, OperatorConfig config, List<String> propertyNames) {
         this.params = params;
         this.config = config;
         this.fullName = params.getActor() + "." + params.getOperation();
+        this.propertyNames = propertyNames;
     }
 
     public Executor getBlockingExecutor() {
@@ -128,6 +139,38 @@ public abstract class OperationPartial implements Operation {
         return params.getOperation();
     }
 
+    /**
+     * Determines if a property has been assigned for the operation.
+     *
+     * @param name property name
+     * @return {@code true} if the given property has been assigned for the operation,
+     *         {@code false} otherwise
+     */
+    public boolean containsProperty(String name) {
+        return properties.containsKey(name);
+    }
+
+    /**
+     * Sets a property.
+     *
+     * @param name property name
+     * @param value new value
+     */
+    public void setProperty(String name, Object value) {
+        properties.put(name, value);
+    }
+
+    /**
+     * Gets a property's value.
+     *
+     * @param name name of the property of interest
+     * @return the property's value, or {@code null} if it has no value
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getProperty(String name) {
+        return (T) properties.get(name);
+    }
+
     @Override
     public CompletableFuture<OperationOutcome> start() {
         // allocate a controller for the entire operation
@@ -236,6 +279,10 @@ public abstract class OperationPartial implements Operation {
      *         {@code null} if this operation has no guard
      */
     protected CompletableFuture<OperationOutcome> startGuardAsync() {
+        if (params.isPreprocessed()) {
+            return null;
+        }
+
         // get the guard payload
         Map<String, Object> payload = makeGuardPayload();
 
@@ -253,6 +300,7 @@ public abstract class OperationPartial implements 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());
@@ -289,6 +337,7 @@ public abstract class OperationPartial implements Operation {
 
     /**
      * Generates and sets {@link #subRequestId} to a new subrequest ID.
+     *
      * @param attempt attempt number, typically starting with 1
      */
     public void generateSubRequestId(int attempt) {
@@ -989,30 +1038,24 @@ public abstract class OperationPartial implements Operation {
     }
 
     /**
-     * Logs a response. If the response is not of type, String, then it attempts to
+     * Logs a message. If the message is not of type, String, then it attempts to
      * pretty-print it into JSON before logging.
      *
      * @param direction IN or OUT
      * @param infra communication infrastructure on which it was published
      * @param source source name (e.g., the URL or Topic name)
-     * @param response response to be logged
+     * @param message message to be logged
      * @return the JSON text that was logged
      */
-    public <T> String logMessage(EventType direction, CommInfrastructure infra, String source, T response) {
+    public <T> String logMessage(EventType direction, CommInfrastructure infra, String source, T message) {
         String json;
         try {
-            if (response == null) {
-                json = null;
-            } else if (response instanceof String) {
-                json = response.toString();
-            } else {
-                json = makeCoder().encode(response, true);
-            }
+            json = prettyPrint(message);
 
-        } catch (CoderException e) {
+        } catch (IllegalArgumentException e) {
             String type = (direction == EventType.IN ? "response" : "request");
             logger.warn("cannot pretty-print {}", type, e);
-            json = response.toString();
+            json = message.toString();
         }
 
         logger.info("[{}|{}|{}|]{}{}", direction, infra, source, NetLoggerUtil.SYSTEM_LS, json);
@@ -1020,6 +1063,28 @@ public abstract class OperationPartial implements Operation {
         return json;
     }
 
+    /**
+     * Converts a message to a "pretty-printed" String using the operation's normal
+     * serialization provider (i.e., it's <i>coder</i>).
+     *
+     * @param message response to be logged
+     * @return the JSON text that was logged
+     * @throws IllegalArgumentException if the message cannot be converted
+     */
+    public <T> String prettyPrint(T message) {
+        if (message == null) {
+            return null;
+        } else if (message instanceof String) {
+            return message.toString();
+        } else {
+            try {
+                return getCoder().encode(message, true);
+            } catch (CoderException e) {
+                throw new IllegalArgumentException("cannot encode message", e);
+            }
+        }
+    }
+
     // these may be overridden by subclasses or junit tests
 
     /**
@@ -1055,7 +1120,7 @@ public abstract class OperationPartial implements Operation {
 
     // these may be overridden by junit tests
 
-    protected Coder makeCoder() {
+    protected Coder getCoder() {
         return coder;
     }
 }