Passing taskParameters from ApexConfig to policy logic 12/102012/2
authora.sreekumar <ajith.sreekumar@est.tech>
Thu, 13 Feb 2020 11:17:54 +0000 (11:17 +0000)
committera.sreekumar <ajith.sreekumar@est.tech>
Thu, 20 Feb 2020 17:03:05 +0000 (17:03 +0000)
TaskParameters can be used to pass parameters from ApexConfig to the policy logic. In the config, these are optional.
Usage as below:

{
  "engineParameters": {
    "taskParameters": [
      {
        "key": "ParameterKey1",
        "value": "ParameterValue1"
      },
      {
        "taskId": "TaskIdVal",
        "key": "ParameterKey2",
        "value": "ParameterValue2"
      }
    ]
  }
}

In the taskLogic, taskParameters can be accessed as below:
eg:  executor.parameters.get("ParameterKey1"))

If taskId is provided in ApexConfig for an entry, then that
parameter is updated only for that particular task. Otherwise, the task
parameter is added to all tasks.

Change-Id: I9e1b3d3697428309e7d86db40b63ffe822935b69
Issue-ID: POLICY-2364
Signed-off-by: a.sreekumar <ajith.sreekumar@est.tech>
core/core-engine/src/main/java/org/onap/policy/apex/core/engine/EngineParameters.java
core/core-engine/src/main/java/org/onap/policy/apex/core/engine/TaskParameters.java [new file with mode: 0644]
core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/TaskExecutor.java
core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContext.java
core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/impl/ExecutorFactoryImpl.java
core/core-engine/src/test/java/org/onap/policy/apex/core/engine/EngineParametersTest.java
core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java
core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java
services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParametersJsonAdapter.java

index d76d8e5..3ca7415 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.apex.core.engine;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.TreeMap;
-
+import lombok.Getter;
+import lombok.Setter;
 import org.onap.policy.apex.context.parameters.ContextParameters;
 import org.onap.policy.common.parameters.GroupValidationResult;
 import org.onap.policy.common.parameters.ParameterGroup;
+import org.onap.policy.common.parameters.ValidationResult;
 
 /**
  * This class holds the parameters for a single Apex engine. This parameter class holds parameters for context schemas
@@ -44,6 +49,8 @@ import org.onap.policy.common.parameters.ParameterGroup;
  *
  * @author Liam Fallon (liam.fallon@ericsson.com)
  */
+@Getter
+@Setter
 public class EngineParameters implements ParameterGroup {
     private ContextParameters contextParameters = new ContextParameters();
 
@@ -53,6 +60,9 @@ public class EngineParameters implements ParameterGroup {
     // A map of parameters for executors of various logic types
     private Map<String, ExecutorParameters> executorParameterMap = new TreeMap<>();
 
+    // A list of parameters to be passed to the task, so that they can be used in the logic
+    private List<TaskParameters> taskParameters = new ArrayList<>();
+
     /**
      * Constructor to create an engine parameters instance and register the instance with the parameter service.
      */
@@ -63,52 +73,6 @@ public class EngineParameters implements ParameterGroup {
         this.name = EngineParameterConstants.MAIN_GROUP_NAME;
     }
 
-    /**
-     * Gets the parameters for context schema and album handling.
-     *
-     * @return the parameters for context schema and album handling
-     */
-    public ContextParameters getContextParameters() {
-        return contextParameters;
-    }
-
-    /**
-     * Sets the parameters for context schema and album handling.
-     *
-     * @param contextParameters the parameters for context schema and album handling
-     */
-    public void setContextParameters(final ContextParameters contextParameters) {
-        this.contextParameters = contextParameters;
-    }
-
-    /**
-     * Gets the executor parameter map of the engine.
-     *
-     * @return the executor parameter map of the engine
-     */
-    public Map<String, ExecutorParameters> getExecutorParameterMap() {
-        return executorParameterMap;
-    }
-
-    /**
-     * Sets the executor parameter map of the engine.
-     *
-     * @param executorParameterMap the executor parameter map of the engine
-     */
-    public void setExecutorParameterMap(final Map<String, ExecutorParameters> executorParameterMap) {
-        this.executorParameterMap = executorParameterMap;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public void setName(final String name) {
-        this.name = name;
-    }
-
     @Override
     public GroupValidationResult validate() {
         final GroupValidationResult result = new GroupValidationResult(this);
@@ -118,6 +82,13 @@ public class EngineParameters implements ParameterGroup {
         for (Entry<String, ExecutorParameters> executorParEntry : executorParameterMap.entrySet()) {
             result.setResult("executorParameterMap", executorParEntry.getKey(), executorParEntry.getValue().validate());
         }
+        for (TaskParameters taskParam : taskParameters) {
+            ValidationResult taskParamValidationResult = taskParam.validate("taskParameters");
+            result.setResult(taskParamValidationResult.getName(), taskParamValidationResult.getStatus(),
+                taskParamValidationResult.getResult());
+        }
         return result;
     }
+
+
 }
diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/TaskParameters.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/TaskParameters.java
new file mode 100644 (file)
index 0000000..8a0f6db
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.core.engine;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.common.parameters.BeanValidator;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+
+/**
+ * This class provides the configurable parameters for Apex Tasks.
+ *
+ * @author Ajith Sreekumar (ajith.sreekumar@est.tech)
+ */
+@Getter
+@Setter
+public class TaskParameters {
+    private String name;
+
+    // If taskId is not specified, then the taskParameter is added to all tasks in the engine.
+    private String taskId;
+
+    @NotNull
+    @NotBlank
+    private String key;
+    @NotNull
+    @NotBlank
+    private String value;
+
+    public TaskParameters() {
+        this.name = "taskParameters";
+    }
+
+    public TaskParameters(String key, String value, String taskId) {
+        this();
+        this.key = key;
+        this.value = value;
+        this.taskId = taskId;
+    }
+
+    /**
+     * Validates the parameters.
+     *
+     * @param resultName name of the result
+     *
+     * @return the validation result
+     */
+    public ValidationResult validate(String resultName) {
+        return new BeanValidator().validateTop(resultName, this);
+    }
+}
index 50abeea..0150b65 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
- *  Modifications Copyright (C) 2019 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,24 +23,28 @@ package org.onap.policy.apex.core.engine.executor;
 
 import static org.onap.policy.common.utils.validation.Assertions.argumentOfClassNotNull;
 
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
-
+import lombok.Getter;
 import lombok.NonNull;
-
 import org.onap.policy.apex.context.ContextException;
 import org.onap.policy.apex.core.engine.ExecutorParameters;
+import org.onap.policy.apex.core.engine.TaskParameters;
 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
 import org.onap.policy.apex.core.engine.executor.context.TaskExecutionContext;
 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
 import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
 import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
 import org.slf4j.ext.XLogger;
 import org.slf4j.ext.XLoggerFactory;
 
@@ -71,17 +75,9 @@ public abstract class TaskExecutor
     // The task execution context; contains the facades for events and context to be used by tasks
     // executed by this task
     // executor
+    @Getter
     private TaskExecutionContext executionContext = null;
 
-    /**
-     * Gets the execution internalContext.
-     *
-     * @return the execution context
-     */
-    protected TaskExecutionContext getExecutionContext() {
-        return executionContext;
-    }
-
     /**
      * {@inheritDoc}.
      */
@@ -238,6 +234,28 @@ public abstract class TaskExecutor
         getOutgoing().put(field, getIncoming().get(field));
     }
 
+    /**
+     * If taskParameters are provided in ApexConfig, then they will be updated in the Tasks.
+     * If taskId is empty, the task parameter is added/updated to all available tasks
+     * Otherwise, the task parameter is added/updated to the corresponding task only.
+     *
+     * @param taskParametersFromConfig the list of task parameters provided in ApexConfig during deployment
+     */
+    public void updateTaskParameters(List<TaskParameters> taskParametersFromConfig) {
+        Map<String, AxTaskParameter> taskParameters = getSubject().getTaskParameters();
+        if (null == taskParameters) {
+            taskParameters = new HashMap<>();
+        }
+        for (TaskParameters taskParameterFromConfig : taskParametersFromConfig) {
+            if (null == taskParameterFromConfig.getTaskId()
+                || getSubject().getId().equals(taskParameterFromConfig.getTaskId())) {
+                taskParameters.put(taskParameterFromConfig.getKey(),
+                    new AxTaskParameter(new AxReferenceKey(), taskParameterFromConfig.getValue()));
+            }
+        }
+        getSubject().setTaskParameters(taskParameters);
+    }
+
     /**
      * {@inheritDoc}.
      */
index b322cf4..6c670b9 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,14 +23,13 @@ package org.onap.policy.apex.core.engine.executor.context;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.TreeMap;
-
 import lombok.Getter;
 import lombok.Setter;
-
 import org.onap.policy.apex.context.ContextAlbum;
 import org.onap.policy.apex.context.ContextRuntimeException;
 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
@@ -38,6 +38,7 @@ import org.onap.policy.apex.core.engine.executor.TaskExecutor;
 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
 import org.slf4j.ext.XLogger;
 import org.slf4j.ext.XLoggerFactory;
 
@@ -103,6 +104,10 @@ public class TaskExecutionContext {
     @Getter
     private Properties executionProperties;
 
+    // Parameters associated to a task
+    @Getter
+    private Map<String, String> parameters = new HashMap<>();
+
     /**
      * Instantiates a new task execution context.
      *
@@ -120,6 +125,9 @@ public class TaskExecutionContext {
         // The subject is the task definition
         subject = new AxTaskFacade(axTask);
 
+        // Populate parameters to be accessed in the task logic from the task parameters.
+        populateParameters(axTask.getTaskParameters());
+
         // Execution ID is the current policy execution instance
         this.executionId = executionId;
         this.executionProperties = executionProperties;
@@ -150,6 +158,16 @@ public class TaskExecutionContext {
         }
     }
 
+    /**
+     * Populate parameters to be accessed in the task logic.
+     *
+     * @param taskParameters The task parameters
+     */
+    private void populateParameters(Map<String, AxTaskParameter> taskParameters) {
+        taskParameters.entrySet().forEach(taskParamEntry -> parameters.put(taskParamEntry.getKey(),
+            taskParamEntry.getValue().getTaskParameterValue()));
+    }
+
     /**
      * Return a context album if it exists in the context definition of this task.
      *
index ca80db9..231f6bc 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
- *  Modifications Copyright (C) 2019 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ package org.onap.policy.apex.core.engine.executor.impl;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.TreeMap;
-
 import org.onap.policy.apex.core.engine.EngineParameterConstants;
 import org.onap.policy.apex.core.engine.EngineParameters;
 import org.onap.policy.apex.core.engine.ExecutorParameters;
@@ -54,6 +53,7 @@ public class ExecutorFactoryImpl implements ExecutorFactory {
     // Get a reference to the logger
     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ExecutorFactoryImpl.class);
 
+    private final EngineParameters engineParameters;
     // A map of logic flavours mapped to executor classes for plugins to executors for those logic flavours
     private Map<String, Class<Executor<?, ?, ?, ?>>> taskExecutorPluginClassMap = new TreeMap<>();
     private Map<String, Class<Executor<?, ?, ?, ?>>> taskSelectionExecutorPluginClassMap = new TreeMap<>();
@@ -68,7 +68,7 @@ public class ExecutorFactoryImpl implements ExecutorFactory {
      * @throws StateMachineException on plugin creation errors
      */
     public ExecutorFactoryImpl() throws StateMachineException {
-        final EngineParameters engineParameters = ParameterService.get(EngineParameterConstants.MAIN_GROUP_NAME);
+        engineParameters = ParameterService.get(EngineParameterConstants.MAIN_GROUP_NAME);
 
         Assertions.argumentOfClassNotNull(engineParameters, StateMachineException.class,
                         "Parameter \"engineParameters\" may not be null");
@@ -121,7 +121,7 @@ public class ExecutorFactoryImpl implements ExecutorFactory {
                         taskExecutorPluginClassMap.get(task.getTaskLogic().getLogicFlavour()), TaskExecutor.class);
         taskExecutor.setParameters(implementationParameterMap.get(task.getTaskLogic().getLogicFlavour()));
         taskExecutor.setContext(parentExecutor, task, context);
-
+        taskExecutor.updateTaskParameters(engineParameters.getTaskParameters());
         return taskExecutor;
     }
 
index 1b34897..ba936f2 100644 (file)
@@ -1,19 +1,20 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * 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.
- * 
+ *
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
 package org.onap.policy.apex.core.engine;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
-
 import org.junit.Test;
 import org.onap.policy.apex.context.parameters.ContextParameters;
 import org.onap.policy.common.parameters.ParameterService;
@@ -41,20 +44,47 @@ public class EngineParametersTest {
         EngineParameters pars = new EngineParameters();
         pars.setName("Name");
         assertEquals("Name", pars.getName());
-        
+
         ContextParameters contextPars = new ContextParameters();
 
         pars.setContextParameters(contextPars);
         assertEquals(contextPars, pars.getContextParameters());
-        
+
         Map<String, ExecutorParameters> executorParameterMap = new LinkedHashMap<>();
         executorParameterMap.put("Executor", new ExecutorParameters());
         pars.setExecutorParameterMap(executorParameterMap);
         assertEquals(executorParameterMap, pars.getExecutorParameterMap());
-        
+
+        List<TaskParameters> taskParameters = new ArrayList<>();
+        taskParameters.add(new TaskParameters("param1key", "param1value", "param1taskId"));
+        taskParameters.add(new TaskParameters("param1key", "param1value", null));
+        pars.setTaskParameters(taskParameters);
         assertTrue(pars.validate().isValid());
-        
+
         ParameterService.register(pars);
         ParameterService.deregister(pars);
     }
+
+    @Test
+    public void test_invalid() {
+        EngineParameters pars = new EngineParameters();
+        pars.setName("Name");
+        assertEquals("Name", pars.getName());
+
+        ContextParameters contextPars = new ContextParameters();
+
+        pars.setContextParameters(contextPars);
+        assertEquals(contextPars, pars.getContextParameters());
+
+        Map<String, ExecutorParameters> executorParameterMap = Map.of("Executor", new ExecutorParameters());
+        pars.setExecutorParameterMap(executorParameterMap);
+        assertEquals(executorParameterMap, pars.getExecutorParameterMap());
+
+        pars.setTaskParameters(List.of(new TaskParameters(null, "param1value", "param1taskId")));
+        assertFalse(pars.validate().isValid());
+        pars.setTaskParameters(List.of(new TaskParameters(" ", "param1value", "param1taskId")));
+        assertFalse(pars.validate().isValid());
+        pars.setTaskParameters(List.of(new TaskParameters("param1key", "", "param1taskId")));
+        assertFalse(pars.validate().isValid());
+    }
 }
index 8b9d1bc..8d1aa5f 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
- *  Modifications Copyright (C) 2019 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ package org.onap.policy.apex.core.engine.executor;
 
 import java.util.Map;
 import java.util.Properties;
-
 import org.onap.policy.apex.context.ContextException;
 import org.onap.policy.apex.core.engine.event.EnEvent;
 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
@@ -71,7 +70,7 @@ public class DummyTaskExecutor extends TaskExecutor {
     @Override
     public AxTask getSubject() {
         if (!override) {
-            super.getSubject();
+            return super.getSubject();
         }
 
         AxArtifactKey taskKey = new AxArtifactKey("FirstTask:0.0.1");
index eb2d111..81b7d94 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.apex.core.engine.executor;
 
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.onap.policy.apex.context.ContextException;
 import org.onap.policy.apex.core.engine.ExecutorParameters;
+import org.onap.policy.apex.core.engine.TaskParameters;
 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
 import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
 import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
 import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
 
 /**
  * Test task excutor.
@@ -75,6 +83,7 @@ public class TaskExecutorTest {
 
     private LinkedHashMap<String, Object> inFieldMap;
     private LinkedHashMap<String, Object> outFieldMap;
+    private List<TaskParameters> taskParametersFromConfig;
 
     /**
      * Set up mocking.
@@ -111,12 +120,20 @@ public class TaskExecutorTest {
         Mockito.doReturn(taskLogicMock).when(axTaskMock).getTaskLogic();
 
         Mockito.doReturn(new AxArtifactKey("Context:0.0.1")).when(internalContextMock).getKey();
+
+        Map<String, AxTaskParameter> taskParameters = new HashMap<>();
+        taskParameters.put("parameterKey2", new AxTaskParameter(new AxReferenceKey(), "parameterOriginalValue2"));
+        Mockito.doReturn(taskParameters).when(axTaskMock).getTaskParameters();
+
+        taskParametersFromConfig = new ArrayList<>();
+        taskParametersFromConfig.add(new TaskParameters("parameterKey0", "parameterNewValue0", "Task0:0.0.1"));
+        taskParametersFromConfig.add(new TaskParameters("parameterKey1", "parameterNewValue1", "Task1:0.0.1"));
+        taskParametersFromConfig.add(new TaskParameters("parameterKey2", "parameterNewValue2", null));
     }
 
     @Test
-    public void testTaskExecutor() {
-        DummyTaskExecutor executor = new DummyTaskExecutor();
-
+    public void testTaskExecutor() throws StateMachineException, ContextException {
+        final DummyTaskExecutor executor = new DummyTaskExecutor();
         executor.setContext(null, axTaskMock, internalContextMock);
         assertEquals("Task0:0.0.1", executor.getKey().getId());
         assertEquals(null, executor.getExecutionContext());
@@ -133,135 +150,81 @@ public class TaskExecutorTest {
         executor.setNext(null);
         assertEquals(null, executor.getNext());
 
-        try {
-            executor.cleanUp();
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("cleanUp() not implemented on class", ex.getMessage());
-        }
+        assertThatThrownBy(() -> executor.cleanUp()).hasMessageContaining("cleanUp() not implemented on class");
 
         Mockito.doReturn(null).when(taskLogicMock).getLogic();
 
-        try {
-            executor.prepare();
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("task logic cannot be null.", ex.getMessage());
-        }
+        assertThatThrownBy(() -> executor.prepare()).hasMessageContaining("task logic cannot be null.");
 
         Mockito.doReturn("some task logic").when(taskLogicMock).getLogic();
 
-        try {
-            executor.prepare();
-        } catch (StateMachineException e) {
-            fail("test should not throw an exception");
-        }
+        executor.prepare();
 
         Map<String, Object> incomingFields = new LinkedHashMap<>();
-        try {
-            executor.executePre(0, new Properties(), incomingFields);
-        } catch (Exception ex) {
-            assertEquals("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"", ex.getMessage());
-        }
+
+        assertThatThrownBy(() -> executor.executePre(0, new Properties(), incomingFields))
+            .hasMessageContaining("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"");
 
         incomingFields.put("InField0", "A Value");
-        try {
-            executor.executePre(0, new Properties(), incomingFields);
-        } catch (Exception e) {
-            fail("test should not throw an exception");
-        }
-
-        try {
-            executor.execute(0, new Properties(), incomingFields);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("execute() not implemented on abstract TaskExecutor class, only on its subclasses",
-                    ex.getMessage());
-        }
-
-        try {
-            executor.execute(0, new Properties(), incomingFields);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("execute() not implemented on abstract TaskExecutor class, only on its subclasses",
-                    ex.getMessage());
-        }
-
-        try {
-            executor.executePost(false);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1",
-                    ex.getMessage());
-        }
+
+        executor.executePre(0, new Properties(), incomingFields);
+
+        assertThatThrownBy(() -> executor.execute(0, new Properties(), incomingFields))
+            .hasMessageContaining("execute() not implemented on abstract TaskExecutor class, only on its subclasses");
+
+        assertThatThrownBy(() -> executor.executePost(false)).hasMessageContaining(
+            "execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1");
 
         executor.getExecutionContext().setMessage("Execution message");
-        try {
-            executor.executePost(false);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1, "
-                    + "user message: Execution message", ex.getMessage());
-        }
-
-        try {
-            executor.executePost(true);
-        } catch (Exception e) {
-            fail("test should not throw an exception");
-        }
+
+        assertThatThrownBy(() -> executor.executePost(false)).hasMessageContaining(
+            "execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1, "
+                + "user message: Execution message");
+
+        executor.executePost(true);
 
         outFieldMap.put("MissingField", axMissingOutputFieldMock);
-        try {
-            executor.executePost(true);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("task output fields \"[MissingField]\" are missing for task \"Task0:0.0.1\"", ex.getMessage());
-        }
+
+        assertThatThrownBy(() -> executor.executePost(true))
+            .hasMessageContaining("task output fields \"[MissingField]\" are missing for task \"Task0:0.0.1\"");
 
         outFieldMap.remove("MissingField");
         executor.getExecutionContext().outFields.put("BadExtraField", "Howdy!");
-        try {
-            executor.executePost(true);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("task output fields \"[BadExtraField]\" are unwanted for task \"Task0:0.0.1\"",
-                    ex.getMessage());
-        }
+
+        assertThatThrownBy(() -> executor.executePost(true))
+            .hasMessageContaining("task output fields \"[BadExtraField]\" are unwanted for task \"Task0:0.0.1\"");
 
         executor.getExecutionContext().outFields.remove("BadExtraField");
         outFieldMap.put("InField1", axMissingOutputFieldMock);
-        try {
-            executor.executePost(true);
-        } catch (Exception ex) {
-            fail("test should not throw an exception");
-        }
+        executor.executePost(true);
 
         outFieldMap.put("InField0", axMissingOutputFieldMock);
-        try {
-            executor.executePost(true);
-        } catch (Exception ex) {
-            fail("test should not throw an exception");
-        }
+        executor.executePost(true);
 
         executor.getExecutionContext().outFields.put("InField0", "Output Value");
-        try {
-            executor.executePost(true);
-        } catch (Exception ex) {
-            fail("test should not throw an exception");
-        }
+        executor.executePost(true);
 
         executor.getExecutionContext().outFields.remove("InField0");
-        try {
-            executor.executePost(true);
-        } catch (Exception ex) {
-            fail("test should not throw an exception");
-        }
-
-        try {
-            executor.executePre(0, null, incomingFields);
-            fail("test should throw an exception");
-        } catch (Exception ex) {
-            assertEquals("executionProperties is marked @NonNull but is null", ex.getMessage());
-        }
+        executor.executePost(true);
+
+        assertThatThrownBy(() -> executor.executePre(0, null, incomingFields))
+            .hasMessageContaining("executionProperties is marked @NonNull but is null");
+    }
+
+    @Test
+    public void testTaskExecutorForTaskParameters() {
+        DummyTaskExecutor executorForParmeterTest = new DummyTaskExecutor(false);
+
+        executorForParmeterTest.setContext(null, axTaskMock, internalContextMock);
+        executorForParmeterTest.updateTaskParameters(taskParametersFromConfig);
+        assertNotNull(executorForParmeterTest.getSubject().getTaskParameters());
+        // taskId matched, parameter value updated with the new value
+        assertEquals("parameterNewValue0",
+            executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey0").getTaskParameterValue());
+        // taskId mismatch, so the parameter is not updated in the task
+        assertNull(executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey1"));
+        // taskId is not available, so parameter is updated in the task
+        assertEquals("parameterNewValue2",
+            executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey2").getTaskParameterValue());
     }
 }
index 29c536e..f8bdc4b 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.apex.core.engine.executor.context;
 
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
 
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -38,7 +39,9 @@ import org.onap.policy.apex.context.ContextAlbum;
 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
 import org.onap.policy.apex.core.engine.executor.TaskExecutor;
 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
 
 /**
  * Test Task Execution Context.
@@ -69,6 +72,11 @@ public class TaskExecutionContextTest {
 
         Mockito.doReturn(contextAlbumReferences).when(axTaskMock).getContextAlbumReferences();
 
+        Map<String, AxTaskParameter> taskParameters = new HashMap<>();
+        taskParameters.put("parameterKey1", new AxTaskParameter(new AxReferenceKey(), "parameterValue1"));
+        taskParameters.put("parameterKey2", new AxTaskParameter(new AxReferenceKey(), "parameterValue2"));
+        Mockito.doReturn(taskParameters).when(axTaskMock).getTaskParameters();
+
         Map<AxArtifactKey, ContextAlbum> contextAlbumMap = new LinkedHashMap<>();
         AxArtifactKey album0Key = new AxArtifactKey("AlbumKey0:0.0.1");
         AxArtifactKey album1Key = new AxArtifactKey("AlbumKey1:0.0.1");
@@ -97,12 +105,11 @@ public class TaskExecutionContextTest {
         ContextAlbum contextAlbum = tec.getContextAlbum("AlbumKey0");
         assertEquals("AlbumKey0:0.0.1", contextAlbum.getKey().getId());
 
-        try {
-            tec.getContextAlbum("AlbumKeyNonExistant");
-            fail("test should throw an exception");
-        } catch (Exception exc) {
-            assertEquals("cannot find definition of context album \"AlbumKeyNonExistant\" on task \"null\"",
-                            exc.getMessage());
-        }
+        Map<String, String> parameters = tec.getParameters();
+        assertEquals("parameterValue1", parameters.get("parameterKey1"));
+        assertEquals("parameterValue2", parameters.get("parameterKey2"));
+
+        assertThatThrownBy(() -> tec.getContextAlbum("AlbumKeyNonExistant"))
+            .hasMessageContaining("cannot find definition of context album \"AlbumKeyNonExistant\" on task \"null\"");
     }
 }
index 1b8daca..5319d76 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
- *  Modifications Copyright (C) 2019 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,10 +28,10 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonSerializationContext;
 import com.google.gson.JsonSerializer;
-
 import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map.Entry;
-
 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
 import org.onap.policy.apex.context.parameters.ContextParameters;
 import org.onap.policy.apex.context.parameters.DistributorParameters;
@@ -41,8 +41,11 @@ import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
 import org.onap.policy.apex.context.parameters.SchemaParameters;
 import org.onap.policy.apex.core.engine.EngineParameters;
 import org.onap.policy.apex.core.engine.ExecutorParameters;
+import org.onap.policy.apex.core.engine.TaskParameters;
 import org.onap.policy.common.parameters.ParameterGroup;
 import org.onap.policy.common.parameters.ParameterRuntimeException;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
 import org.slf4j.ext.XLogger;
 import org.slf4j.ext.XLoggerFactory;
 
@@ -67,6 +70,8 @@ public class EngineServiceParametersJsonAdapter
     private static final String EXECUTOR_PARAMETERS     = "executorParameters";
     // @formatter:on
 
+    private static StandardCoder standardCoder = new StandardCoder();
+
     /**
      * {@inheritDoc}.
      */
@@ -98,9 +103,37 @@ public class EngineServiceParametersJsonAdapter
         // Executor parameter wrangling
         getExecutorParameters(engineParametersJsonObject, engineParameters, context);
 
+        // Task parameter wrangling
+        getTaskParametersList(engineParametersJsonObject, engineParameters);
         return engineParameters;
     }
 
+    /**
+     * Method to get the task parameters list for Apex.
+     *
+     * @param engineParametersJsonObject The input JSON
+     * @param engineParameters The output parameters
+     */
+    private void getTaskParametersList(JsonObject engineParametersJsonObject, EngineParameters engineParameters) {
+        final JsonElement parametersElement = engineParametersJsonObject.get("taskParameters");
+
+        // configurable parameters are optional so if the element does not exist, just return
+        if (parametersElement == null) {
+            return;
+        }
+        List<TaskParameters> parametersList = new ArrayList<>();
+        parametersElement.getAsJsonArray().forEach(taskParam -> {
+            TaskParameters parameters = null;
+            try {
+                parameters = standardCoder.decode(standardCoder.encode(taskParam), TaskParameters.class);
+            } catch (CoderException e) {
+                throw new ParameterRuntimeException("Error reading taskParameters from the config json provided.");
+            }
+            parametersList.add(parameters);
+        });
+        engineParameters.setTaskParameters(parametersList);
+    }
+
     /**
      * Get the context parameters for Apex.
      *