aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@est.tech>2020-03-23 17:49:50 +0000
committerliamfallon <liam.fallon@est.tech>2020-03-24 17:40:27 +0000
commit2f75e9d08d1e47e2b9b39ec21653bc3b4d65d00a (patch)
treebe5374421d8b3f026175ab51d197289ea9dbbe0d
parentf7746d758149bc68584c01dc0fe15130c7a866b1 (diff)
Launch separate threads for Javascript task execution
When a policy is loaded, a separate thread is spawned for each Javascript script executor. This allows us to precompile the Javascript scripts and also to have a larger stack available for script execution. Issue-ID: POLICY-2106 Change-Id: I97323aafb623ba537ac1889b3c9504b345b4f67e Signed-off-by: liamfallon <liam.fallon@est.tech>
-rw-r--r--examples/examples-decisionmaker/src/main/resources/logic/MakeDecisionStateTSL.js6
-rw-r--r--examples/examples-decisionmaker/src/main/resources/policy/DecisionMakerPolicyModel.apex26
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java192
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutor.java13
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutor.java17
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutor.java16
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java54
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java42
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java35
-rw-r--r--plugins/plugins-executor/plugins-executor-javascript/src/test/resources/logback-test.xml41
10 files changed, 346 insertions, 96 deletions
diff --git a/examples/examples-decisionmaker/src/main/resources/logic/MakeDecisionStateTSL.js b/examples/examples-decisionmaker/src/main/resources/logic/MakeDecisionStateTSL.js
index 33af49534..e49438d14 100644
--- a/examples/examples-decisionmaker/src/main/resources/logic/MakeDecisionStateTSL.js
+++ b/examples/examples-decisionmaker/src/main/resources/logic/MakeDecisionStateTSL.js
@@ -34,9 +34,9 @@ else if (executor.inFields.get("mode").equals("optimistic")) {
else if (executor.inFields.get("mode").equals("dithering")) {
executor.subject.getTaskKey("DitheringAnswerTask").copyTo(executor.selectedTask);
}
-//else if (executor.inFields.get("mode").equals("roundrobin")) {
-// executor.subject.getTaskKey("RoundRobinAnswerTask").copyTo(executor.selectedTask);
-//}
+else if (executor.inFields.get("mode").equals("roundrobin")) {
+ executor.subject.getTaskKey("RoundRobinAnswerTask").copyTo(executor.selectedTask);
+}
executor.logger.info("Answer Selected Task:" + executor.selectedTask);
diff --git a/examples/examples-decisionmaker/src/main/resources/policy/DecisionMakerPolicyModel.apex b/examples/examples-decisionmaker/src/main/resources/policy/DecisionMakerPolicyModel.apex
index 295afa159..672ff894f 100644
--- a/examples/examples-decisionmaker/src/main/resources/policy/DecisionMakerPolicyModel.apex
+++ b/examples/examples-decisionmaker/src/main/resources/policy/DecisionMakerPolicyModel.apex
@@ -113,18 +113,18 @@ task logic create name=DitheringAnswerTask logicFlavour=JAVASCRIPT logic=LS
#MACROFILE:"src/main/resources/logic/DitheringAnswerTask.js"
LE
-#task create name=RoundRobinAnswerTask
-#
-#task inputfield create name=RoundRobinAnswerTask fieldName=mode schemaName=SimpleStringType
-#
-#task outputfield create name=RoundRobinAnswerTask fieldName=decision schemaName=SimpleStringType
-#
-#task contextref create name=RoundRobinAnswerTask albumName=AnswerAlbum
-#task contextref create name=RoundRobinAnswerTask albumName=LastAnswerAlbum
-#
-#task logic create name=RoundRobinAnswerTask logicFlavour=JAVASCRIPT logic=LS
-##MACROFILE:"src/main/resources/logic/RoundRobinAnswerTask.js"
-#LE
+task create name=RoundRobinAnswerTask
+
+task inputfield create name=RoundRobinAnswerTask fieldName=mode schemaName=SimpleStringType
+
+task outputfield create name=RoundRobinAnswerTask fieldName=decision schemaName=SimpleStringType
+
+task contextref create name=RoundRobinAnswerTask albumName=AnswerAlbum
+task contextref create name=RoundRobinAnswerTask albumName=LastAnswerAlbum
+
+task logic create name=RoundRobinAnswerTask logicFlavour=JAVASCRIPT logic=LS
+#MACROFILE:"src/main/resources/logic/RoundRobinAnswerTask.js"
+LE
policy create name=AnswerInitPolicy template=freestyle firstState=AnswerInitState
@@ -140,7 +140,7 @@ policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState
policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState taskName=PessimisticAnswerTask outputType=DIRECT outputName=DecisionFinalOutput
policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState taskName=OptimisticAnswerTask outputType=DIRECT outputName=DecisionFinalOutput
policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState taskName=DitheringAnswerTask outputType=DIRECT outputName=DecisionFinalOutput
-#policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState taskName=RoundRobinAnswerTask outputType=DIRECT outputName=DecisionFinalOutput
+policy state taskref create name=DecisionMakerPolicy stateName=MakeDecisionState taskName=RoundRobinAnswerTask outputType=DIRECT outputName=DecisionFinalOutput
policy state selecttasklogic create name=DecisionMakerPolicy stateName=MakeDecisionState logicFlavour=JAVASCRIPT logic=LS
#MACROFILE:"src/main/resources/logic/MakeDecisionStateTSL.js"
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java
index c80f58fbe..2394b83d3 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java
@@ -20,19 +20,28 @@
package org.onap.policy.apex.plugins.executor.javascript;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicReference;
+
import org.apache.commons.lang3.StringUtils;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
/**
* The Class JavascriptExecutor is the executor for task logic written in Javascript.
*
* @author Liam Fallon (liam.fallon@ericsson.com)
*/
-public class JavascriptExecutor {
+public class JavascriptExecutor implements Runnable {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptExecutor.class);
+
public static final int DEFAULT_OPTIMIZATION_LEVEL = 9;
// Recurring string constants
@@ -41,16 +50,28 @@ public class JavascriptExecutor {
// The key of the subject that wants to execute Javascript code
final AxKey subjectKey;
+ private String javascriptCode;
private Context javascriptContext;
private Script script;
+ private final BlockingQueue<Object> executionQueue = new LinkedBlockingQueue<>();
+ private final BlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>();
+
+ private final Thread executorThread;
+ private CountDownLatch intializationLatch = new CountDownLatch(1);
+ private CountDownLatch shutdownLatch = new CountDownLatch(1);
+ private AtomicReference<StateMachineException> executorException = new AtomicReference<>(null);
+
/**
- * Initializes the Javascripe executor.
+ * Initializes the Javascript executor.
*
* @param subjectKey the key of the subject that is requesting Javascript execution
*/
public JavascriptExecutor(final AxKey subjectKey) {
this.subjectKey = subjectKey;
+
+ executorThread = new Thread(this);
+ executorThread.setName(this.getClass().getSimpleName() + ":" + subjectKey.getId());
}
/**
@@ -60,10 +81,143 @@ public class JavascriptExecutor {
* @throws StateMachineException thrown when instantiation of the executor fails
*/
public void init(final String javascriptCode) throws StateMachineException {
+ LOGGER.debug("JavascriptExecutor {} starting ... ", subjectKey.getId());
+
+ if (executorThread.isAlive()) {
+ throw new StateMachineException(
+ "initiation failed, executor " + subjectKey.getId() + " is already running");
+ }
+
if (StringUtils.isEmpty(javascriptCode)) {
throw new StateMachineException("no logic specified for " + subjectKey.getId());
}
+ this.javascriptCode = javascriptCode;
+
+ try {
+ executorThread.start();
+ } catch (Exception e) {
+ throw new StateMachineException("initiation failed, executor " + subjectKey.getId() + " failed to start",
+ e);
+ }
+
+ try {
+ intializationLatch.await();
+ } catch (InterruptedException e) {
+ LOGGER.debug("JavascriptExecutor {} interrupted on execution thread startup", subjectKey.getId(), e);
+ Thread.currentThread().interrupt();
+ }
+
+ if (executorException.get() != null) {
+ clearAndThrowExecutorException();
+ }
+
+ LOGGER.debug("JavascriptExecutor {} started ... ", subjectKey.getId());
+ }
+
+ /**
+ * Execute a Javascript script.
+ *
+ * @param executionContext the execution context to use for script execution
+ * @return true if execution was successful, false otherwise
+ * @throws StateMachineException on execution errors
+ */
+ public boolean execute(final Object executionContext) throws StateMachineException {
+ if (!executorThread.isAlive()) {
+ throw new StateMachineException("execution failed, executor " + subjectKey.getId() + " is not running");
+ }
+
+ executionQueue.add(executionContext);
+
+ boolean result = false;
+
+ try {
+ result = resultQueue.take();
+ } catch (final InterruptedException e) {
+ LOGGER.debug("JavascriptExecutor {} interrupted on execution result wait", subjectKey.getId(), e);
+ Thread.currentThread().interrupt();
+ }
+
+ if (executorException.get() != null) {
+ clearAndThrowExecutorException();
+ }
+
+ return result;
+ }
+
+ /**
+ * Cleans up the executor after processing.
+ *
+ * @throws StateMachineException thrown when cleanup of the executor fails
+ */
+ public void cleanUp() throws StateMachineException {
+ if (!executorThread.isAlive()) {
+ throw new StateMachineException("cleanup failed, executor " + subjectKey.getId() + " is not running");
+ }
+
+ executorThread.interrupt();
+
+ try {
+ shutdownLatch.await();
+ } catch (InterruptedException e) {
+ LOGGER.debug("JavascriptExecutor {} interrupted on execution clkeanup wait", subjectKey.getId(), e);
+ Thread.currentThread().interrupt();
+ }
+
+ if (executorException.get() != null) {
+ clearAndThrowExecutorException();
+ }
+ }
+
+ @Override
+ public void run() {
+ LOGGER.debug("JavascriptExecutor {} initializing ... ", subjectKey.getId());
+
+ try {
+ initExecutor();
+ } catch (StateMachineException sme) {
+ LOGGER.warn("JavascriptExecutor {} initialization failed", sme);
+ executorException.set(sme);
+ intializationLatch.countDown();
+ return;
+ }
+
+ intializationLatch.countDown();
+
+ LOGGER.debug("JavascriptExecutor {} executing ... ", subjectKey.getId());
+
+ // Take jobs from the execution queue of the worker and execute them
+ while (!executorThread.isInterrupted()) {
+ try {
+ Object contextObject = executionQueue.take();
+ if (contextObject == null) {
+ break;
+ }
+
+ resultQueue.add(executeScript(contextObject));
+ } catch (final InterruptedException e) {
+ LOGGER.debug("execution was interruped for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
+ resultQueue.add(false);
+ Thread.currentThread().interrupt();
+ } catch (StateMachineException sme) {
+ executorException.set(sme);
+ resultQueue.add(false);
+ }
+ }
+
+ try {
+ Context.exit();
+ } catch (final Exception e) {
+ executorException.set(new StateMachineException(
+ "executor close failed to close for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e));
+ }
+
+ shutdownLatch.countDown();
+
+ LOGGER.debug("JavascriptExecutor {} completed processing", subjectKey.getId());
+ }
+
+ private void initExecutor() throws StateMachineException {
try {
// Create a Javascript context for this thread
javascriptContext = Context.enter();
@@ -76,18 +230,11 @@ public class JavascriptExecutor {
} catch (Exception e) {
Context.exit();
throw new StateMachineException(
- "logic failed to compile for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
+ "logic failed to compile for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
}
}
- /**
- * Executes the the Javascript code.
- *
- * @param executionContext the execution context of the subject to be passed to the Javascript context
- * @return true if the Javascript executed properly
- * @throws StateMachineException thrown when Javascript execution fails
- */
- public boolean execute(final Object executionContext) throws StateMachineException {
+ private boolean executeScript(final Object executionContext) throws StateMachineException {
Object returnObject = null;
try {
@@ -99,28 +246,25 @@ public class JavascriptExecutor {
returnObject = script.exec(javascriptContext, javascriptScope);
} catch (final Exception e) {
throw new StateMachineException(
- "logic failed to run for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
+ "logic failed to run for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
}
if (!(returnObject instanceof Boolean)) {
throw new StateMachineException(
- "execute: logic for " + subjectKey.getId() + " returned a non-boolean value " + returnObject);
+ "execute: logic for " + subjectKey.getId() + " returned a non-boolean value " + returnObject);
}
return (boolean) returnObject;
}
- /**
- * Cleans up the executor after processing.
- *
- * @throws StateMachineException thrown when cleanup of the executor fails
- */
- public void cleanUp() throws StateMachineException {
- try {
- Context.exit();
- } catch (final Exception e) {
- throw new StateMachineException("cleanUp: executor cleanup failed to close for " + subjectKey.getId()
- + WITH_MESSAGE + e.getMessage(), e);
+ private void clearAndThrowExecutorException() throws StateMachineException {
+ StateMachineException exceptionToThrow = executorException.getAndSet(null);
+ if (exceptionToThrow != null) {
+ throw exceptionToThrow;
}
}
+
+ protected Thread getExecutorThread() {
+ return executorThread;
+ }
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutor.java b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutor.java
index 27e649fd3..63e4948dd 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutor.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutor.java
@@ -53,11 +53,12 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor {
super.prepare();
// Create the executor
- javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ if (javascriptExecutor == null) {
+ javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ }
// Initialize and cleanup the executor to check the Javascript code
javascriptExecutor.init(getSubject().getLogic());
- javascriptExecutor.cleanUp();
}
/**
@@ -72,14 +73,12 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor {
*/
@Override
public String execute(final long executionId, final Properties executionProperties,
- final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
+ final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
// Do execution pre work
executePre(executionId, executionProperties, incomingFields);
// Execute the Javascript executor
- javascriptExecutor.init(getSubject().getLogic());
boolean result = javascriptExecutor.execute(getExecutionContext());
- javascriptExecutor.cleanUp();
// Execute the Javascript
executePost(result);
@@ -95,6 +94,8 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor {
@Override
public void cleanUp() throws StateMachineException {
LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getLogicFlavour() + ","
- + getSubject().getLogic());
+ + getSubject().getLogic());
+
+ javascriptExecutor.cleanUp();
}
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutor.java b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutor.java
index bec5670c5..a9dba27f2 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutor.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutor.java
@@ -53,11 +53,12 @@ public class JavascriptTaskExecutor extends TaskExecutor {
super.prepare();
// Create the executor
- javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ if (javascriptExecutor == null) {
+ javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ }
// Initialize and cleanup the executor to check the Javascript code
javascriptExecutor.init(getSubject().getTaskLogic().getLogic());
- javascriptExecutor.cleanUp();
}
/**
@@ -72,15 +73,13 @@ public class JavascriptTaskExecutor extends TaskExecutor {
*/
@Override
public Map<String, Object> execute(final long executionId, final Properties executionProperties,
- final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
+ final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
// Do execution pre work
executePre(executionId, executionProperties, incomingFields);
// Execute the Javascript executor
- javascriptExecutor.init(getSubject().getTaskLogic().getLogic());
boolean result = javascriptExecutor.execute(getExecutionContext());
- javascriptExecutor.cleanUp();
// Execute the Javascript
executePost(result);
@@ -96,6 +95,12 @@ public class JavascriptTaskExecutor extends TaskExecutor {
@Override
public void cleanUp() throws StateMachineException {
LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getTaskLogic().getLogicFlavour()
- + "," + getSubject().getTaskLogic().getLogic());
+ + "," + getSubject().getTaskLogic().getLogic());
+
+ if (javascriptExecutor != null) {
+ javascriptExecutor.cleanUp();
+ }
+
+ javascriptExecutor = null;
}
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutor.java b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutor.java
index c32b70991..93384c129 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutor.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutor.java
@@ -54,7 +54,9 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor {
super.prepare();
// Create the executor
- javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ if (javascriptExecutor == null) {
+ javascriptExecutor = new JavascriptExecutor(getSubject().getKey());
+ }
// Initialize and cleanup the executor to check the Javascript code
javascriptExecutor.init(getSubject().getTaskSelectionLogic().getLogic());
@@ -72,14 +74,12 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor {
*/
@Override
public AxArtifactKey execute(final long executionId, final Properties executionProperties,
- final EnEvent incomingEvent) throws StateMachineException, ContextException {
+ final EnEvent incomingEvent) throws StateMachineException, ContextException {
// Do execution pre work
executePre(executionId, executionProperties, incomingEvent);
// Execute the Javascript executor
- javascriptExecutor.init(getSubject().getTaskSelectionLogic().getLogic());
boolean result = javascriptExecutor.execute(getExecutionContext());
- javascriptExecutor.cleanUp();
// Execute the Javascript
executePost(result);
@@ -94,8 +94,10 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor {
*/
@Override
public void cleanUp() throws StateMachineException {
- LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + ","
- + getSubject().getTaskSelectionLogic().getLogicFlavour() + ","
- + getSubject().getTaskSelectionLogic().getLogic());
+ LOGGER.debug(
+ "cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getTaskSelectionLogic().getLogicFlavour()
+ + "," + getSubject().getTaskSelectionLogic().getLogic());
+
+ javascriptExecutor.cleanUp();
}
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java
index 8be79558f..d4a346187 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java
@@ -20,6 +20,7 @@
package org.onap.policy.apex.plugins.executor.javascript;
+import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -96,36 +97,59 @@ public class JavascriptStateFinalizerExecutorTest {
assertThatThrownBy(() -> {
jsfe.prepare();
}).hasMessage("logic failed to compile for NULL:0.0.0:NULL:NULL "
- + "with message: invalid return (NULL:0.0.0:NULL:NULL#1)");
+ + "with message: invalid return (NULL:0.0.0:NULL:NULL#1)");
Map<String, Object> incomingParameters1 = new HashMap<>();
assertThatThrownBy(() -> {
jsfe.execute(-1, new Properties(), incomingParameters1);
- }).hasMessage("logic failed to compile for NULL:0.0.0:NULL:NULL "
- + "with message: invalid return (NULL:0.0.0:NULL:NULL#1)");
+ }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not running");
+
+ assertThatThrownBy(() -> {
+ jsfe.prepare();
+ }).hasMessage("initiation failed, executor NULL:0.0.0:NULL:NULL failed to start");
+ assertThatThrownBy(() -> {
+ jsfe.cleanUp();
+ }).hasMessage("cleanup failed, executor NULL:0.0.0:NULL:NULL is not running");
+
+ JavascriptStateFinalizerExecutor jsfe1 = new JavascriptStateFinalizerExecutor();
stateFinalizerLogic.setLogic("java.lang.String");
- jsfe.prepare();
+ jsfe1.setContext(parentStateExcutor, stateFinalizerLogic, internalContext);
+ jsfe1.prepare();
AxEvent axEvent = new AxEvent(new AxArtifactKey("Event", "0.0.1"));
EnEvent event = new EnEvent(axEvent);
- stateFinalizerLogic.setLogic("if(executor.executionId==-1)" + "{\r\n"
- + "var returnValueType = java.lang.Boolean;" + "var returnValue = new returnValueType(false); }\n"
- + "else{\n" + "executor.setSelectedStateOutputName(\"SelectedOutputIsMe\");\n"
- + "var returnValueType = java.lang.Boolean;\n" + "\n"
- + "var returnValue = new returnValueType(true);} true;");
assertThatThrownBy(() -> {
- jsfe.prepare();
- jsfe.execute(-1, new Properties(), event);
- }).hasMessage("execute-post: state finalizer logic \"NULL:0.0.0:NULL:NULL\" did not select an output state");
+ jsfe1.execute(-1, new Properties(), event);
+ }).hasMessage(
+ "execute: logic for NULL:0.0.0:NULL:NULL returned a non-boolean value [JavaClass java.lang.String]");
+
+ assertThatThrownBy(() -> {
+ jsfe1.execute(-1, new Properties(), event);
+ }).hasMessage(
+ "execute: logic for NULL:0.0.0:NULL:NULL returned a non-boolean value [JavaClass java.lang.String]");
+
+ assertThatCode(() -> {
+ jsfe1.cleanUp();
+ }).doesNotThrowAnyException();
+
+ JavascriptStateFinalizerExecutor jsfe2 = new JavascriptStateFinalizerExecutor();
+
+ stateFinalizerLogic.setLogic("executor.setSelectedStateOutputName(\"SelectedOutputIsMe\");\n true;");
+
+ jsfe2.setContext(parentStateExcutor, stateFinalizerLogic, internalContext);
+ assertThatCode(() -> {
+ jsfe2.prepare();
+ }).doesNotThrowAnyException();
state.getStateOutputs().put("SelectedOutputIsMe", null);
- jsfe.prepare();
- String stateOutput = jsfe.execute(0, new Properties(), event);
+ String stateOutput = jsfe2.execute(0, new Properties(), event);
assertEquals("SelectedOutputIsMe", stateOutput);
- jsfe.cleanUp();
+ assertThatCode(() -> {
+ jsfe2.cleanUp();
+ }).doesNotThrowAnyException();
}
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java
index c327ebb4d..b532d6c47 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java
@@ -20,6 +20,7 @@
package org.onap.policy.apex.plugins.executor.javascript;
+import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -64,7 +65,7 @@ public class JavascriptTaskExecutorTest {
public static void prepareForTest() {
final ContextParameters contextParameters = new ContextParameters();
contextParameters.getLockManagerParameters()
- .setPluginClass("org.onap.policy.apex.context.impl.locking.jvmlocal.JvmLocalLockManager");
+ .setPluginClass("org.onap.policy.apex.context.impl.locking.jvmlocal.JvmLocalLockManager");
contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
contextParameters.getDistributorParameters().setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
@@ -98,32 +99,47 @@ public class JavascriptTaskExecutorTest {
@Test
public void testJavascriptTaskExecutor() throws Exception {
- JavascriptTaskExecutor jte = new JavascriptTaskExecutor();
- assertNotNull(jte);
-
assertThatThrownBy(() -> {
- jte.prepare();
+ JavascriptTaskExecutor jteBadPrep = new JavascriptTaskExecutor();
+ jteBadPrep.prepare();
}).isInstanceOf(NullPointerException.class);
AxTask task = new AxTask(new AxArtifactKey("TestTask:0.0.1"));
final ApexInternalContext internalContext = new ApexInternalContext(new AxPolicyModel());
- jte.setContext(null, task, internalContext);
+ JavascriptTaskExecutor jteBadLogic = new JavascriptTaskExecutor();
+ assertNotNull(jteBadLogic);
+
+ jteBadLogic.setContext(null, task, internalContext);
task.getTaskLogic().setLogic("return boolean;");
assertThatThrownBy(() -> {
- jte.prepare();
- jte.execute(-1, new Properties(), null);
+ jteBadLogic.prepare();
}).hasMessage("logic failed to compile for TestTask:0.0.1 with message: invalid return (TestTask:0.0.1#1)");
task.getTaskLogic().setLogic("var x = 5;");
+ JavascriptTaskExecutor jte = new JavascriptTaskExecutor();
+ jte.setContext(null, task, internalContext);
+
jte.prepare();
+
+ assertThatThrownBy(() -> {
+ jte.prepare();
+ }).hasMessage("initiation failed, executor TestTask:0.0.1 is already running");
+
assertThatThrownBy(() -> {
jte.execute(-1, new Properties(), null);
}).isInstanceOf(NullPointerException.class);
- jte.cleanUp();
+
+ assertThatThrownBy(() -> {
+ jte.execute(-1, new Properties(), null);
+ }).isInstanceOf(NullPointerException.class);
+
+ assertThatCode(() -> {
+ jte.cleanUp();
+ }).doesNotThrowAnyException();
task.getTaskLogic().setLogic("var returnValue = false;\nreturnValue;");
@@ -142,6 +158,10 @@ public class JavascriptTaskExecutorTest {
Map<String, Object> returnMap = jte.execute(0, new Properties(), incomingParameters);
assertEquals(0, returnMap.size());
jte.cleanUp();
+
+ assertThatCode(() -> {
+ jte.cleanUp();
+ }).doesNotThrowAnyException();
}
@Test
@@ -188,12 +208,12 @@ public class JavascriptTaskExecutorTest {
private ContextAlbum createTestContextAlbum() throws ContextException {
AxContextSchemas schemas = new AxContextSchemas();
AxContextSchema simpleStringSchema =
- new AxContextSchema(new AxArtifactKey("SimpleStringSchema", "0.0.1"), "JAVA", "java.lang.String");
+ new AxContextSchema(new AxArtifactKey("SimpleStringSchema", "0.0.1"), "JAVA", "java.lang.String");
schemas.getSchemasMap().put(simpleStringSchema.getKey(), simpleStringSchema);
ModelService.registerModel(AxContextSchemas.class, schemas);
AxContextAlbum axContextAlbum = new AxContextAlbum(new AxArtifactKey("TestContextAlbum", "0.0.1"), "Policy",
- true, AxArtifactKey.getNullKey());
+ true, AxArtifactKey.getNullKey());
axContextAlbum.setItemSchema(simpleStringSchema.getKey());
Distributor distributor = new JvmLocalDistributor();
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java
index 3acf132dd..cb577535a 100644
--- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java
@@ -20,6 +20,7 @@
package org.onap.policy.apex.plugins.executor.javascript;
+import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -90,7 +91,7 @@ public class JavascriptTaskSelectExecutorTest {
assertThatThrownBy(() -> {
jtse.execute(-1, new Properties(), event1);
- }).hasMessage("no logic specified for NULL:0.0.0:NULL:NULL");
+ }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not running");
state.getTaskSelectionLogic().setLogic("java.lang.String");
jtse.prepare();
@@ -105,20 +106,32 @@ public class JavascriptTaskSelectExecutorTest {
assertThatThrownBy(() -> {
jtse.execute(-1, new Properties(), event);
}).hasMessage(
- "execute: logic for NULL:0.0.0:NULL:NULL returned a non-boolean value [JavaClass java.lang.String]");
+ "execute: logic for NULL:0.0.0:NULL:NULL returned a non-boolean value [JavaClass java.lang.String]");
- state.getTaskSelectionLogic().setLogic("var x=1;\n" + "false; ");
+ state.getTaskSelectionLogic().setLogic("var x=1;\n" + "false;");
assertThatThrownBy(() -> {
- jtse.prepare();
jtse.execute(-1, new Properties(), event);
- }).hasMessage("execute-post: task selection logic failed on state \"NULL:0.0.0:NULL:NULL\"");
-
- state.getTaskSelectionLogic().setLogic("var x = 1\n" + "true; ");
+ }).hasMessage(
+ "execute: logic for NULL:0.0.0:NULL:NULL returned a non-boolean value [JavaClass java.lang.String]");
- jtse.prepare();
- AxArtifactKey taskKey = jtse.execute(0, new Properties(), event);
- assertEquals("NULL:0.0.0", taskKey.getId());
- jtse.cleanUp();
+ assertThatThrownBy(() -> {
+ jtse.prepare();
+ }).hasMessage("initiation failed, executor NULL:0.0.0:NULL:NULL is already running");
+
+ assertThatCode(() -> {
+ jtse.cleanUp();
+ }).doesNotThrowAnyException();
+
+ JavascriptTaskSelectExecutor jtse1 = new JavascriptTaskSelectExecutor();
+ jtse1.setContext(null, state, internalContext);
+ state.getTaskSelectionLogic().setLogic("var x = 1\n" + "true;");
+
+ assertThatCode(() -> {
+ jtse1.prepare();
+ AxArtifactKey taskKey = jtse1.execute(0, new Properties(), event);
+ assertEquals("NULL:0.0.0", taskKey.getId());
+ jtse1.cleanUp();
+ }).doesNotThrowAnyException();
}
}
diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/resources/logback-test.xml b/plugins/plugins-executor/plugins-executor-javascript/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..f3bc0c8ed
--- /dev/null
+++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/resources/logback-test.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.
+ 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=========================================================
+-->
+
+<configuration>
+ <contextName>Apex</contextName>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <!-- USE FOR STD OUT ONLY -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.onap.policy.apex.plugins.executor.javascript" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+</configuration>