Fix State Finalizer Prepare and Cleanup
The prepare() and cleanup() method were not called on state finalizers
for states. This review adds calls for them.
Issue-ID: POLICY-2450
Change-Id: I27aec4dea51f3e22b5922c04c7b7b974fca24292
Signed-off-by: liamfallon <liam.fallon@est.tech>
diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateExecutor.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateExecutor.java
index caaa184..1926539 100644
--- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateExecutor.java
+++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateExecutor.java
@@ -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.
@@ -97,7 +97,7 @@
*/
@Override
public void setContext(final Executor<?, ?, ?, ?> incomingParent, final AxState incomingAxState,
- final ApexInternalContext incomingContext) {
+ final ApexInternalContext incomingContext) {
// Save the state and context definition
this.parent = incomingParent;
this.axState = incomingAxState;
@@ -108,7 +108,7 @@
// Set a task executor for each task
for (final Entry<AxArtifactKey, AxStateTaskReference> stateTaskReferenceEntry : axState.getTaskReferences()
- .entrySet()) {
+ .entrySet()) {
final AxArtifactKey taskKey = stateTaskReferenceEntry.getKey();
final AxStateTaskReference taskReference = stateTaskReferenceEntry.getValue();
@@ -125,20 +125,20 @@
} else if (taskReference.getStateTaskOutputType().equals(AxStateTaskOutputType.LOGIC)) {
// Get the state finalizer logic for this task
final AxStateFinalizerLogic finalizerLogic =
- axState.getStateFinalizerLogicMap().get(taskReference.getOutput().getLocalName());
+ axState.getStateFinalizerLogicMap().get(taskReference.getOutput().getLocalName());
if (finalizerLogic == null) {
// Finalizer logic for the task does not exist
throw new StateMachineRuntimeException("state finalizer logic on task reference \"" + taskReference
- + "\" on state \"" + axState.getId() + "\" does not exist");
+ + "\" on state \"" + axState.getId() + "\" does not exist");
}
// Create a state finalizer executor for the task
task2StateFinalizerMap.put(taskKey,
- executorFactory.getStateFinalizerExecutor(this, finalizerLogic, context));
+ executorFactory.getStateFinalizerExecutor(this, finalizerLogic, context));
} else {
// This should never happen but.....
throw new StateMachineRuntimeException("invalid state output type on task reference \"" + taskReference
- + "\" on state \"" + axState.getId() + "\"");
+ + "\" on state \"" + axState.getId() + "\"");
}
}
}
@@ -158,6 +158,10 @@
for (final TaskExecutor taskExecutor : taskExecutorMap.values()) {
taskExecutor.prepare();
}
+
+ for (final StateFinalizerExecutor stateFinalizer : task2StateFinalizerMap.values()) {
+ stateFinalizer.prepare();
+ }
}
/**
@@ -165,13 +169,13 @@
*/
@Override
public StateOutput execute(final long executionId, final Properties executionProperties,
- final EnEvent incomingEvent) throws StateMachineException, ContextException {
+ final EnEvent incomingEvent) throws StateMachineException, ContextException {
this.lastIncomingEvent = incomingEvent;
// Check that the incoming event matches the trigger for this state
if (!incomingEvent.getAxEvent().getKey().equals(axState.getTrigger())) {
throw new StateMachineException("incoming event \"" + incomingEvent.getId() + "\" does not match trigger \""
- + axState.getTrigger().getId() + "\" of state \"" + axState.getId() + "\"");
+ + axState.getTrigger().getId() + "\" of state \"" + axState.getId() + "\"");
}
// The key of the task to execute
@@ -194,7 +198,7 @@
final TreeMap<String, Object> incomingValues = new TreeMap<>();
incomingValues.putAll(incomingEvent);
final Map<String, Object> taskExecutionResultMap =
- taskExecutorMap.get(taskKey).execute(executionId, executionProperties, incomingValues);
+ taskExecutorMap.get(taskKey).execute(executionId, executionProperties, incomingValues);
final AxTask task = taskExecutorMap.get(taskKey).getSubject();
// Check if this task has direct output
@@ -207,20 +211,20 @@
final StateFinalizerExecutor finalizerLogicExecutor = task2StateFinalizerMap.get(taskKey);
if (finalizerLogicExecutor == null) {
throw new StateMachineException("state finalizer logic for task \"" + taskKey.getId()
- + "\" not found for state \"" + axState.getId() + "\"");
+ + "\" not found for state \"" + axState.getId() + "\"");
}
// Execute the state finalizer logic to select a state output and to adjust the
// taskExecutionResultMap
stateOutputName =
- finalizerLogicExecutor.execute(executionId, executionProperties, taskExecutionResultMap);
+ finalizerLogicExecutor.execute(executionId, executionProperties, taskExecutionResultMap);
}
// Now look up the the actual state output
final AxStateOutput stateOutputDefinition = axState.getStateOutputs().get(stateOutputName);
if (stateOutputDefinition == null) {
throw new StateMachineException("state output definition for state output \"" + stateOutputName
- + "\" not found for state \"" + axState.getId() + "\"");
+ + "\" not found for state \"" + axState.getId() + "\"");
}
// Create the state output and transfer all the fields across to its event
@@ -242,7 +246,7 @@
return stateOutput;
} catch (final Exception e) {
final String errorMessage = "State execution of state \"" + axState.getId() + "\" on task \""
- + (taskKey != null ? taskKey.getId() : "null") + "\" failed: " + e.getMessage();
+ + (taskKey != null ? taskKey.getId() : "null") + "\" failed: " + e.getMessage();
LOGGER.warn(errorMessage);
throw new StateMachineException(errorMessage, e);
@@ -254,7 +258,7 @@
*/
@Override
public final void executePre(final long executionId, final Properties executionProperties,
- final EnEvent incomingEntity) throws StateMachineException {
+ final EnEvent incomingEntity) throws StateMachineException {
throw new StateMachineException("execution pre work not implemented on class");
}
@@ -277,6 +281,10 @@
// Clean the task selector
taskSelectExecutor.cleanUp();
}
+
+ for (final StateFinalizerExecutor stateFinalizer : task2StateFinalizerMap.values()) {
+ stateFinalizer.cleanUp();
+ }
}
/**
diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java
index 6fb28bc..a46ddfb 100644
--- a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java
+++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java
@@ -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.
@@ -20,6 +21,7 @@
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.fail;
@@ -123,11 +125,8 @@
assertEquals("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"", ex.getMessage());
}
- try {
- executor.executePre(0, null, incomingEvent);
- } catch (Exception ex) {
- assertEquals("executionProperties is marked @NonNull but is null", ex.getMessage());
- }
+ assertThatThrownBy(() -> executor.executePre(0, null, incomingEvent))
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
try {
executor.executePre(0, new Properties(), incomingEvent);
@@ -140,7 +139,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute() not implemented on abstract StateFinalizerExecutionContext class, "
- + "only on its subclasses", ex.getMessage());
+ + "only on its subclasses", ex.getMessage());
}
try {
@@ -148,7 +147,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:NULL:NULL\" "
- + "on finalizer logic null", ex.getMessage());
+ + "on finalizer logic null", ex.getMessage());
}
executor.getExecutionContext().setMessage("Execution message");
@@ -157,7 +156,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:NULL:NULL\" "
- + "on finalizer logic null, user message: Execution message", ex.getMessage());
+ + "on finalizer logic null, user message: Execution message", ex.getMessage());
}
try {
@@ -171,7 +170,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute-post: state finalizer logic \"null\" did not select an output state",
- ex.getMessage());
+ ex.getMessage());
}
try {
@@ -185,9 +184,10 @@
executor.executePost(true);
fail("test should throw an exception");
} catch (Exception ex) {
- assertEquals("execute-post: state finalizer logic \"null\" selected output state "
- + "\"ThisOutputDoesNotExist\" that does not exsist on state \"NULL:0.0.0:NULL:NULL\"",
- ex.getMessage());
+ assertEquals(
+ "execute-post: state finalizer logic \"null\" selected output state "
+ + "\"ThisOutputDoesNotExist\" that does not exsist on state \"NULL:0.0.0:NULL:NULL\"",
+ ex.getMessage());
}
try {
diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java
index c2abd1e..7256b3f 100644
--- a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java
+++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java
@@ -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.
@@ -22,6 +23,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.LinkedHashMap;
@@ -37,7 +39,6 @@
import org.onap.policy.apex.core.engine.ExecutorParameters;
import org.onap.policy.apex.core.engine.context.ApexInternalContext;
import org.onap.policy.apex.core.engine.event.EnEvent;
-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.basicmodel.service.ModelService;
@@ -164,15 +165,15 @@
state1.getTaskReferences().put(task1Key, str1);
Mockito.doReturn(new DummyTaskExecutor(true)).when(executorFactoryMock).getTaskExecutor(Mockito.anyObject(),
- Mockito.anyObject(), Mockito.anyObject());
+ Mockito.anyObject(), Mockito.anyObject());
dummyTsle = new DummyTaskSelectExecutor(true);
Mockito.doReturn(dummyTsle).when(executorFactoryMock).getTaskSelectionExecutor(Mockito.anyObject(),
- Mockito.anyObject(), Mockito.anyObject());
+ Mockito.anyObject(), Mockito.anyObject());
dummySfle = new DummyStateFinalizerExecutor(true);
Mockito.doReturn(dummySfle).when(executorFactoryMock).getStateFinalizerExecutor(Mockito.anyObject(),
- Mockito.anyObject(), Mockito.anyObject());
+ Mockito.anyObject(), Mockito.anyObject());
}
@After
@@ -183,8 +184,8 @@
@Test
public void testStateMachineExecutor() {
- StateMachineExecutor executor = new StateMachineExecutor(executorFactoryMock,
- new AxArtifactKey("OwnerKey:0.0.1"));
+ StateMachineExecutor executor =
+ new StateMachineExecutor(executorFactoryMock, new AxArtifactKey("OwnerKey:0.0.1"));
try {
executor.execute(0, null, incomingEventMock);
@@ -224,8 +225,9 @@
try {
executor.prepare();
- } catch (StateMachineException e) {
- fail("test should not throw an exception");
+ fail("test should throw an exception");
+ } catch (Exception e) {
+ assertTrue(e instanceof NullPointerException);
}
axPolicy.setFirstState("BadState");
@@ -260,11 +262,11 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("state execution failed, next state \"Policy:0.0.1:PName:BadState\" not found",
- ex.getMessage());
+ ex.getMessage());
}
axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1")
- .setNextState(AxReferenceKey.getNullKey());
+ .setNextState(AxReferenceKey.getNullKey());
dummyTsle.setTaskNo(0);
try {
executor.execute(0, null, incomingEventMock);
@@ -279,7 +281,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("incoming event \"Event1:0.0.1\" does not match trigger \"BadTrigger:0.0.1\" "
- + "of state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
+ + "of state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
}
axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("Event1:0.0.1"));
@@ -297,11 +299,11 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("state finalizer logic on task reference "
- + "\"AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=Policy,"
- + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
- + "outputType=LOGIC,output=AxReferenceKey:(parentKeyName=Policy,parentKeyVersion=0.0.1,"
- + "parentLocalName=state1,localName=sfl))\" on state \"Policy:0.0.1:NULL:state1\" "
- + "does not exist", ex.getMessage());
+ + "\"AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=Policy,"
+ + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
+ + "outputType=LOGIC,output=AxReferenceKey:(parentKeyName=Policy,parentKeyVersion=0.0.1,"
+ + "parentLocalName=state1,localName=sfl))\" on state \"Policy:0.0.1:NULL:state1\" " + "does not exist",
+ ex.getMessage());
}
axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", savedSfl);
@@ -317,19 +319,19 @@
AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
try {
axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
- .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
executor.setContext(null, axPolicy, internalContextMock);
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("invalid state output type on task reference \"AxStateTaskReference:(stateKey=AxReferenceKey:"
- + "(parentKeyName=Policy,parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
- + "outputType=UNDEFINED,output=AxReferenceKey:(parentKeyName=Policy,"
- + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=sfl))\" "
- + "on state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
+ + "(parentKeyName=Policy,parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
+ + "outputType=UNDEFINED,output=AxReferenceKey:(parentKeyName=Policy,"
+ + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=sfl))\" "
+ + "on state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
}
axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
- .setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ .setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
executor.setContext(null, axPolicy, internalContextMock);
dummyTsle.setTaskNo(0);
@@ -346,8 +348,8 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("State execution of state \"Policy:0.0.1:NULL:state1\" on task \"task1:0.0.1\" failed: "
- + "state output definition for state output \"stateOutputBad\" not found for "
- + "state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
+ + "state output definition for state output \"stateOutputBad\" not found for "
+ + "state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
}
dummyTsle.setTaskNo(0);
@@ -360,15 +362,16 @@
try {
executor.cleanUp();
+ fail("test should throw an exception");
} catch (Exception ex) {
- fail("test should not throw an exception");
+ assertEquals("cleanUp() not implemented on class", ex.getMessage());
}
}
@Test
public void testStateOutput() {
- StateOutput output = new StateOutput(
- axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
+ StateOutput output =
+ new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
assertNotNull(output);
assertEquals("stateOutput0", output.getStateOutputDefinition().getKey().getLocalName());
@@ -401,7 +404,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("field definitions and values do not match for event Event1:0.0.1\n[]\n[key]",
- ex.getMessage());
+ ex.getMessage());
}
AxField axBadFieldDefinition = new AxField();
diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
index 81b7d94..a9218ea 100644
--- a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
+++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
@@ -32,6 +32,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -208,7 +209,7 @@
executor.executePost(true);
assertThatThrownBy(() -> executor.executePre(0, null, incomingFields))
- .hasMessageContaining("executionProperties is marked @NonNull but is null");
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
}
@Test
diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java
index 8e907e1..817b161 100644
--- a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java
+++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java
@@ -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.
@@ -20,6 +21,7 @@
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.fail;
@@ -151,7 +153,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute-post: task selection logic failed on state \"State0Parent:0.0.1:Parent:State0\"",
- ex.getMessage());
+ ex.getMessage());
}
executor.getExecutionContext().setMessage("Execution message");
@@ -160,7 +162,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("execute-post: task selection logic failed on state \"State0Parent:0.0.1:Parent:State0\", "
- + "user message: Execution message", ex.getMessage());
+ + "user message: Execution message", ex.getMessage());
}
try {
@@ -188,7 +190,7 @@
fail("test should throw an exception");
} catch (Exception ex) {
assertEquals("task \"IDontExist:0.0.0\" returned by task selection logic not defined "
- + "on state \"State0Parent:0.0.1:Parent:State0\"", ex.getMessage());
+ + "on state \"State0Parent:0.0.1:Parent:State0\"", ex.getMessage());
}
try {
@@ -206,11 +208,7 @@
fail("test should not throw an exception");
}
- try {
- executor.executePre(0, null, incomingEvent);
- fail("test should throw an exception");
- } catch (Exception ex) {
- assertEquals("executionProperties is marked @NonNull but is null", ex.getMessage());
- }
+ assertThatThrownBy(() -> executor.executePre(0, null, incomingEvent))
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
}
}