570b33b2a6afd16ef4472aebd905820b40062caa
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.plugins.executor.javascript;
22
23 import javax.script.Compilable;
24 import javax.script.CompiledScript;
25 import javax.script.ScriptEngine;
26 import javax.script.ScriptEngineManager;
27 import javax.script.ScriptException;
28
29 import org.onap.policy.apex.context.ContextException;
30 import org.onap.policy.apex.core.engine.event.EnEvent;
31 import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor;
32 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
33 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
34 import org.slf4j.ext.XLogger;
35 import org.slf4j.ext.XLoggerFactory;
36
37 /**
38  * The Class JavascriptTaskSelectExecutor is the task selection executor for task selection logic written in Javascript
39  * It is unlikely that this is thread safe.
40  *
41  * @author Liam Fallon (liam.fallon@ericsson.com)
42  */
43 public class JavascriptTaskSelectExecutor extends TaskSelectExecutor {
44     // Logger for this class
45     private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptTaskSelectExecutor.class);
46
47     // Javascript engine
48     private ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
49     private CompiledScript compiled = null;
50
51     /**
52      * Prepares the task for processing.
53      *
54      * @throws StateMachineException thrown when a state machine execution error occurs
55      */
56     @Override
57     public void prepare() throws StateMachineException {
58         // Call generic prepare logic
59         super.prepare();
60         try {
61             compiled = ((Compilable) engine).compile(getSubject().getTaskSelectionLogic().getLogic());
62         } catch (final ScriptException e) {
63             LOGGER.error("execute: task selection logic failed to compile for state  \"" + getSubject().getKey().getId()
64                     + "\"");
65             throw new StateMachineException(
66                     "task selection logic failed to compile for state  \"" + getSubject().getKey().getId() + "\"", e);
67         }
68
69     }
70
71     /**
72      * Executes the executor for the task in a sequential manner.
73      *
74      * @param executionID the execution ID for the current APEX policy execution
75      * @param incomingEvent the incoming event
76      * @return The outgoing event
77      * @throws StateMachineException on an execution error
78      * @throws ContextException on context errors
79      */
80     @Override
81     public AxArtifactKey execute(final long executionID, final EnEvent incomingEvent)
82             throws StateMachineException, ContextException {
83         // Do execution pre work
84         executePre(executionID, incomingEvent);
85
86         // Set up the Javascript engine
87         engine.put("executor", getExecutionContext());
88
89         // Check and execute the Javascript logic
90         boolean returnValue = false;
91         try {
92             if (compiled == null) {
93                 engine.eval(getSubject().getTaskSelectionLogic().getLogic());
94             } else {
95                 compiled.eval(engine.getContext());
96             }
97         } catch (final ScriptException e) {
98             LOGGER.error(
99                     "execute: task selection logic failed to run for state  \"" + getSubject().getKey().getId() + "\"");
100             throw new StateMachineException(
101                     "task selection logic failed to run for state  \"" + getSubject().getKey().getId() + "\"", e);
102         }
103
104         try {
105             final Object ret = engine.get("returnValue");
106             if (ret == null) {
107                 LOGGER.error("execute: task selection logic failed to set a return value for state  \""
108                         + getSubject().getKey().getId() + "\"");
109                 throw new StateMachineException(
110                         "execute: task selection logic failed to set a return value for state  \""
111                                 + getSubject().getKey().getId() + "\"");
112             }
113             returnValue = (Boolean) ret;
114         } catch (NullPointerException | ClassCastException e) {
115             LOGGER.error("execute: task selection logic failed to set a correct return value for state  \""
116                     + getSubject().getKey().getId() + "\"", e);
117             throw new StateMachineException("execute: task selection logic failed to set a return value for state  \""
118                     + getSubject().getKey().getId() + "\"", e);
119         }
120
121         // Do the execution post work
122         executePost(returnValue);
123
124         // Send back the return event
125         if (returnValue) {
126             return getOutgoing();
127         } else {
128             return null;
129         }
130     }
131
132     /**
133      * Cleans up the task after processing.
134      *
135      * @throws StateMachineException thrown when a state machine execution error occurs
136      */
137     @Override
138     public void cleanUp() throws StateMachineException {
139         LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + ","
140                 + getSubject().getTaskSelectionLogic().getLogicFlavour() + ","
141                 + getSubject().getTaskSelectionLogic().getLogic());
142         engine = null;
143     }
144 }