2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.plugins.executor.javascript;
23 import org.apache.commons.lang3.StringUtils;
24 import org.mozilla.javascript.Context;
25 import org.mozilla.javascript.Script;
26 import org.mozilla.javascript.Scriptable;
27 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
28 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
31 * The Class JavascriptExecutor is the executor for task logic written in Javascript.
33 * @author Liam Fallon (liam.fallon@ericsson.com)
35 public class JavascriptExecutor {
36 public static final int DEFAULT_OPTIMIZATION_LEVEL = 9;
38 // Recurring string constants
39 private static final String WITH_MESSAGE = " with message: ";
41 // The key of the subject that wants to execute Javascript code
42 final AxKey subjectKey;
44 private Context javascriptContext;
45 private Script script;
48 * Initializes the Javascripe executor.
50 * @param subjectKey the key of the subject that is requesting Javascript execution
52 public JavascriptExecutor(final AxKey subjectKey) {
53 this.subjectKey = subjectKey;
57 * Prepares the executor for processing and compiles the Javascript code.
59 * @param javascriptCode the Javascript code to execute
60 * @throws StateMachineException thrown when instantiation of the executor fails
62 public void init(final String javascriptCode) throws StateMachineException {
63 if (StringUtils.isEmpty(javascriptCode)) {
64 throw new StateMachineException("no logic specified for " + subjectKey.getId());
68 // Create a Javascript context for this thread
69 javascriptContext = Context.enter();
71 // Set up the default values of the context
72 javascriptContext.setOptimizationLevel(DEFAULT_OPTIMIZATION_LEVEL);
73 javascriptContext.setLanguageVersion(Context.VERSION_1_8);
75 script = javascriptContext.compileString(javascriptCode, subjectKey.getId(), 1, null);
76 } catch (Exception e) {
78 throw new StateMachineException(
79 "logic failed to compile for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
84 * Executes the the Javascript code.
86 * @param executionContext the execution context of the subject to be passed to the Javascript context
87 * @return true if the Javascript executed properly
88 * @throws StateMachineException thrown when Javascript execution fails
90 public boolean execute(final Object executionContext) throws StateMachineException {
91 Object returnObject = null;
94 // Pass the subject context to the Javascript engine
95 Scriptable javascriptScope = javascriptContext.initStandardObjects();
96 javascriptScope.put("executor", javascriptScope, executionContext);
99 returnObject = script.exec(javascriptContext, javascriptScope);
100 } catch (final Exception e) {
101 throw new StateMachineException(
102 "logic failed to run for " + subjectKey.getId() + WITH_MESSAGE + e.getMessage(), e);
105 if (!(returnObject instanceof Boolean)) {
106 throw new StateMachineException(
107 "execute: logic for " + subjectKey.getId() + " returned a non-boolean value " + returnObject);
110 return (boolean) returnObject;
114 * Cleans up the executor after processing.
116 * @throws StateMachineException thrown when cleanup of the executor fails
118 public void cleanUp() throws StateMachineException {
121 } catch (final Exception e) {
122 throw new StateMachineException("cleanUp: executor cleanup failed to close for " + subjectKey.getId()
123 + WITH_MESSAGE + e.getMessage(), e);