diff options
Diffstat (limited to 'plugins/plugins-executor/plugins-executor-javascript/src/main')
4 files changed, 132 insertions, 128 deletions
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 new file mode 100644 index 000000000..93f6216fc --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-javascript/src/main/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutor.java @@ -0,0 +1,108 @@ +/*- + * ============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.plugins.executor.javascript; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; +import org.graalvm.polyglot.Value; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxKey; + +/** + * The Class JavascriptExecutor is the executor for task logic written in Javascript. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JavascriptExecutor { + // The key of the subject that wants to execute Javascript code + final AxKey subjectKey; + + // The Javascript context + private final Context jsContext; + + /** + * Prepares the executor for processing. + * + * @param subjectKey the key of the subject that is requesting Javascript execution + * @throws StateMachineException thrown when instantiation of the executor fails + */ + public JavascriptExecutor(final AxKey subjectKey) throws StateMachineException { + this.subjectKey = subjectKey; + + // @formatter:off + jsContext = + Context.newBuilder("js") + .allowHostClassLookup(s -> true) + .allowHostAccess(HostAccess.ALL) + .build(); + // @formatter:on + + try { + jsContext.getBindings("js"); + } catch (Exception e) { + jsContext.close(); + throw new StateMachineException( + "prepare: javascript engine failed to initialize properly for \"" + subjectKey.getId() + "\"", e); + } + } + + /** + * Executes the the Javascript code. + * + * @param executionContext the execution context of the subject to be passed to the Javascript context + * @param javascriptCode the Javascript code to execute + * @return true if the Javascript executed properly + * @throws StateMachineException thrown when Javascript execution fails + */ + public boolean execute(final Object executionContext, final String javascriptCode) throws StateMachineException { + try { + // Set up the Javascript engine context + jsContext.getBindings("js").putMember("executor", executionContext); + jsContext.eval("js", javascriptCode); + + } catch (final Exception e) { + throw new StateMachineException("execute: logic failed to run for \"" + subjectKey.getId() + "\"", e); + } + + Value returnValue = jsContext.getBindings("js").getMember("returnValue"); + + if (returnValue == null || returnValue.isNull()) { + throw new StateMachineException( + "execute: logic failed to set a return value for \"" + subjectKey.getId() + "\""); + } + + return returnValue.asBoolean(); + } + + /** + * Cleans up the executor after processing. + * + * @throws StateMachineException thrown when cleanup of the executor fails + */ + public void cleanUp() throws StateMachineException { + try { + jsContext.close(); + } catch (final Exception e) { + throw new StateMachineException( + "cleanUp: executor cleanup failed to close for \"" + subjectKey.getId() + "\"", e); + } + } +} 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 cd660c807..18a6ef58a 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 @@ -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,11 +24,6 @@ package org.onap.policy.apex.plugins.executor.javascript; import java.util.Map; import java.util.Properties; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; import org.onap.policy.apex.context.ContextException; import org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor; import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; @@ -45,9 +40,7 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor { // Logger for this class private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptStateFinalizerExecutor.class); - // Javascript engine - private ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); - private CompiledScript compiled = null; + private JavascriptExecutor javascriptExecutor; /** * Prepares the state finalizer for processing. @@ -58,14 +51,8 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor { public void prepare() throws StateMachineException { // Call generic prepare logic super.prepare(); - try { - compiled = ((Compilable) engine).compile(getSubject().getLogic()); - } catch (final ScriptException e) { - LOGGER.error("execute: state finalizer logic failed to compile for state finalizer \"" - + getSubject().getKey().getId() + "\""); - throw new StateMachineException("state finalizer logic failed to compile for state finalizer \"" - + getSubject().getKey().getId() + "\"", e); - } + + javascriptExecutor = new JavascriptExecutor(getSubject().getKey()); } /** @@ -84,25 +71,8 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor { // Do execution pre work executePre(executionId, executionProperties, incomingFields); - // Set up the Javascript engine - engine.put("executor", getExecutionContext()); - - // Check and execute the Javascript logic - try { - if (compiled == null) { - engine.eval(getSubject().getLogic()); - } else { - compiled.eval(engine.getContext()); - } - } catch (final ScriptException e) { - LOGGER.error("execute: state finalizer logic failed to run for state finalizer \"" - + getSubject().getKey().getId() + "\""); - throw new StateMachineException("state finalizer logic failed to run for state finalizer \"" - + getSubject().getKey().getId() + "\"", e); - } - - // Do the execution post work - executePost((boolean) engine.get("returnValue")); + // Execute the Javascript and do post processing + executePost(javascriptExecutor.execute(getExecutionContext(), getSubject().getLogic())); return getOutgoing(); } @@ -116,6 +86,7 @@ public class JavascriptStateFinalizerExecutor extends StateFinalizerExecutor { public void cleanUp() throws StateMachineException { LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getLogicFlavour() + "," + getSubject().getLogic()); - engine = null; + + 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 9769f42db..29fae193e 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 @@ -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,11 +24,6 @@ package org.onap.policy.apex.plugins.executor.javascript; import java.util.Map; import java.util.Properties; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; import org.onap.policy.apex.context.ContextException; import org.onap.policy.apex.core.engine.executor.TaskExecutor; import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; @@ -45,9 +40,7 @@ public class JavascriptTaskExecutor extends TaskExecutor { // Logger for this class private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptTaskExecutor.class); - // Javascript engine - private ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); - private CompiledScript compiled = null; + private JavascriptExecutor javascriptExecutor; /** * Prepares the task for processing. @@ -58,13 +51,8 @@ public class JavascriptTaskExecutor extends TaskExecutor { public void prepare() throws StateMachineException { // Call generic prepare logic super.prepare(); - try { - compiled = ((Compilable) engine).compile(getSubject().getTaskLogic().getLogic()); - } catch (final ScriptException e) { - LOGGER.error("execute: task logic failed to compile for task \"" + getSubject().getKey().getId() + "\""); - throw new StateMachineException( - "task logic failed to compile for task \"" + getSubject().getKey().getId() + "\"", e); - } + + javascriptExecutor = new JavascriptExecutor(getSubject().getKey()); } /** @@ -83,32 +71,8 @@ public class JavascriptTaskExecutor extends TaskExecutor { // Do execution pre work executePre(executionId, executionProperties, incomingFields); - // Set up the Javascript engine - engine.put("executor", getExecutionContext()); - - // Check and execute the Javascript logic - try { - if (compiled == null) { - engine.eval(getSubject().getTaskLogic().getLogic()); - } else { - compiled.eval(engine.getContext()); - } - } catch (final ScriptException e) { - LOGGER.error("execute: task logic failed to run for task \"" + getSubject().getKey().getId() + "\""); - throw new StateMachineException( - "task logic failed to run for task \"" + getSubject().getKey().getId() + "\"", e); - } - - final Object ret = engine.get("returnValue"); - if (ret == null) { - LOGGER.error("execute: task logic failed to set a return value for task \"" + getSubject().getKey().getId() - + "\""); - throw new StateMachineException("execute: task logic failed to set a return value for task \"" - + getSubject().getKey().getId() + "\""); - } - - // Do the execution post work - executePost((Boolean) ret); + // Execute the Javascript and do post processing + executePost(javascriptExecutor.execute(getExecutionContext(), getSubject().getTaskLogic().getLogic())); return getOutgoing(); } @@ -122,6 +86,7 @@ public class JavascriptTaskExecutor extends TaskExecutor { public void cleanUp() throws StateMachineException { LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getTaskLogic().getLogicFlavour() + "," + getSubject().getTaskLogic().getLogic()); - engine = null; + + javascriptExecutor.cleanUp(); } } 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 afc7d0183..41585fbd0 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 @@ -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,11 +23,6 @@ package org.onap.policy.apex.plugins.executor.javascript; import java.util.Properties; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; import org.onap.policy.apex.context.ContextException; import org.onap.policy.apex.core.engine.event.EnEvent; import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor; @@ -46,16 +41,10 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor { // Logger for this class private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptTaskSelectExecutor.class); - // Recurring string constants - private static final String TSL_FAILED_PREFIX = - "execute: task selection logic failed to set a return value for state \""; - - // Javascript engine - private ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); - private CompiledScript compiled = null; + private JavascriptExecutor javascriptExecutor; /** - * Prepares the task for processing. + * Prepares the task selection logic for processing. * * @throws StateMachineException thrown when a state machine execution error occurs */ @@ -63,15 +52,8 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor { public void prepare() throws StateMachineException { // Call generic prepare logic super.prepare(); - try { - compiled = ((Compilable) engine).compile(getSubject().getTaskSelectionLogic().getLogic()); - } catch (final ScriptException e) { - LOGGER.error("execute: task selection logic failed to compile for state \"" + getSubject().getKey().getId() - + "\""); - throw new StateMachineException( - "task selection logic failed to compile for state \"" + getSubject().getKey().getId() + "\"", e); - } + javascriptExecutor = new JavascriptExecutor(getSubject().getKey()); } /** @@ -90,31 +72,8 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor { // Do execution pre work executePre(executionId, executionProperties, incomingEvent); - // Set up the Javascript engine - engine.put("executor", getExecutionContext()); - - // Check and execute the Javascript logic - try { - if (compiled == null) { - engine.eval(getSubject().getTaskSelectionLogic().getLogic()); - } else { - compiled.eval(engine.getContext()); - } - } catch (final ScriptException e) { - LOGGER.error( - "execute: task selection logic failed to run for state \"" + getSubject().getKey().getId() + "\""); - throw new StateMachineException( - "task selection logic failed to run for state \"" + getSubject().getKey().getId() + "\"", e); - } - - final Object ret = engine.get("returnValue"); - if (ret == null) { - LOGGER.error(TSL_FAILED_PREFIX + getSubject().getKey().getId() + "\""); - throw new StateMachineException(TSL_FAILED_PREFIX + getSubject().getKey().getId() + "\""); - } - - // Do the execution post work - executePost((Boolean) ret); + // Execute the Javascript and do post processing + executePost(javascriptExecutor.execute(getExecutionContext(), getSubject().getTaskSelectionLogic().getLogic())); return getOutgoing(); } @@ -129,6 +88,7 @@ public class JavascriptTaskSelectExecutor extends TaskSelectExecutor { LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getTaskSelectionLogic().getLogicFlavour() + "," + getSubject().getTaskSelectionLogic().getLogic()); - engine = null; + + javascriptExecutor.cleanUp(); } } |