From d48fd41c995cca495a945da4c183a70bff765dea Mon Sep 17 00:00:00 2001 From: ramverma Date: Mon, 11 Jun 2018 11:27:47 +0100 Subject: Adding plugin-executor module to apex-pdp Change-Id: I711eaaff3707aa6398c26f1a124fedeb1d0e11f4 Issue-ID: POLICY-862 Signed-off-by: ramverma --- .../executor/jython/JythonExecutorParameters.java | 42 ++++++ .../jython/JythonStateFinalizerExecutor.java | 131 ++++++++++++++++++ .../executor/jython/JythonTaskExecutor.java | 147 ++++++++++++++++++++ .../executor/jython/JythonTaskSelectExecutor.java | 150 +++++++++++++++++++++ .../apex/plugins/executor/jython/package-info.java | 30 +++++ 5 files changed, 500 insertions(+) create mode 100644 plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonExecutorParameters.java create mode 100644 plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonStateFinalizerExecutor.java create mode 100644 plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskExecutor.java create mode 100644 plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskSelectExecutor.java create mode 100644 plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/package-info.java (limited to 'plugins/plugins-executor/plugins-executor-jython/src') diff --git a/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonExecutorParameters.java b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonExecutorParameters.java new file mode 100644 index 000000000..7a22013f1 --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonExecutorParameters.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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.jython; + +import org.onap.policy.apex.core.engine.ExecutorParameters; + +/** + * This class provides executor parameters for the Jython Executor plugin. It specifies the classes that provide the + * Jython implementations of the abstract classes {@link org.onap.policy.apex.core.engine.executor.TaskExecutor}, + * {@link org.onap.policy.apex.core.engine.executor.TaskSelectExecutor}, and + * {@link org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor}. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JythonExecutorParameters extends ExecutorParameters { + /** + * Constructor that sets the abstract implementation classes. + */ + public JythonExecutorParameters() { + this.setTaskExecutorPluginClass(JythonTaskExecutor.class.getCanonicalName()); + this.setTaskSelectionExecutorPluginClass(JythonTaskSelectExecutor.class.getCanonicalName()); + this.setStateFinalizerExecutorPluginClass(JythonStateFinalizerExecutor.class.getCanonicalName()); + } +} diff --git a/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonStateFinalizerExecutor.java b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonStateFinalizerExecutor.java new file mode 100644 index 000000000..26512b52d --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonStateFinalizerExecutor.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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.jython; + +import java.util.Map; + +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; +import org.python.core.Py; +import org.python.core.PyCode; +import org.python.core.PyException; +import org.python.util.PythonInterpreter; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class JythonStateFinalizerExecutor is the state finalizer executor for state finalizer logic written in Jython It + * is unlikely that this is thread safe. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JythonStateFinalizerExecutor extends StateFinalizerExecutor { + // Logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(JythonStateFinalizerExecutor.class); + + // The Jython interpreter + private final PythonInterpreter interpreter = new PythonInterpreter(); + private PyCode compiled = null; + + /** + * Prepares the state finalizer for processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void prepare() throws StateMachineException { + interpreter.setErr(System.err); + interpreter.setOut(System.out); + + // Call generic prepare logic + super.prepare(); + try { + synchronized (Py.class) { + compiled = Py.compile_flags(getSubject().getLogic(), "<" + getSubject().getKey().toString() + ">", + "exec", null); + } + } catch (final PyException e) { + LOGGER.warn("failed to compile Jython code for state finalizer " + getSubject().getKey(), e); + throw new StateMachineException( + "failed to compile Jython code for state finalizer " + getSubject().getKey(), e); + } + + } + + /** + * Executes the executor for the state finalizer logic in a sequential manner. + * + * @param executionID the execution ID for the current APEX policy execution + * @param incomingFields the incoming fields for finalisation + * @return The state output for the state + * @throws StateMachineException on an execution error + * @throws ContextException on context errors + */ + @Override + public String execute(final long executionID, final Map incomingFields) + throws StateMachineException, ContextException { + + boolean returnValue = false; + + // Do execution pre work + executePre(executionID, incomingFields); + + try { + + // Check and execute the Jython logic + /* Precompiled Version */ + synchronized (Py.class) { + // Set up the Jython engine + interpreter.set("executor", getExecutionContext()); + interpreter.exec(compiled); + returnValue = (boolean) interpreter.get("returnValue", java.lang.Boolean.class); + } + /* */ + } catch (final Exception e) { + LOGGER.warn("failed to execute Jython code for state finalizer " + getSubject().getKey(), e); + throw new StateMachineException( + "failed to execute Jython code for state finalizer " + getSubject().getKey(), e); + } + + // Do the execution post work + executePost(returnValue); + + // Send back the return event + if (returnValue) { + return getOutgoing(); + } else { + return null; + } + } + + /** + * Cleans up the state finalizer after processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void cleanUp() throws StateMachineException { + interpreter.cleanup(); + LOGGER.debug("cleanUp:" + getSubject().getKey() + "," + getSubject().getLogicFlavour() + "," + + getSubject().getLogic()); + } +} diff --git a/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskExecutor.java b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskExecutor.java new file mode 100644 index 000000000..4387a5df7 --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskExecutor.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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.jython; + +import java.util.Map; + +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; +import org.python.core.Py; +import org.python.core.PyCode; +import org.python.core.PyException; +import org.python.util.PythonInterpreter; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class JythonTaskExecutor is the task executor for task logic written in Jython It is unlikely that this is thread + * safe. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JythonTaskExecutor extends TaskExecutor { + // Logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(JythonTaskExecutor.class); + + // The Jython interpreter + private final PythonInterpreter interpreter = new PythonInterpreter(); + private PyCode compiled = null; + + /** + * Prepares the task for processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void prepare() throws StateMachineException { + interpreter.setErr(System.err); + interpreter.setOut(System.out); + + // Call generic prepare logic + super.prepare(); + try { + synchronized (Py.class) { + compiled = Py.compile_flags(getSubject().getTaskLogic().getLogic(), + "<" + getSubject().getKey().toString() + ">", "exec", null); + } + } catch (final PyException e) { + LOGGER.warn("failed to compile Jython code for task " + getSubject().getKey().getID(), e); + throw new StateMachineException("failed to compile Jython code for task " + getSubject().getKey().getID(), + e); + } + + } + + /** + * Executes the executor for the task in a sequential manner. + * + * @param executionID the execution ID for the current APEX policy execution + * @param incomingFields the incoming fields + * @return The outgoing fields + * @throws StateMachineException on an execution error + * @throws ContextException on context errors + */ + @Override + public Map execute(final long executionID, final Map incomingFields) + throws StateMachineException, ContextException { + + boolean returnValue = false; + + // Do execution pre work + executePre(executionID, incomingFields); + + try { + + // Check and execute the Jython logic + /* Precompiled Version */ + synchronized (Py.class) { + // Set up the Jython engine + interpreter.set("executor", getExecutionContext()); + interpreter.exec(compiled); + try { + final Object ret = interpreter.get("returnValue", java.lang.Boolean.class); + 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() + "\""); + } + returnValue = (Boolean) ret; + } catch (NullPointerException | ClassCastException e) { + LOGGER.error("execute: task selection logic failed to set a correct return value for state \"" + + getSubject().getKey().getID() + "\"", e); + throw new StateMachineException( + "execute: task selection logic failed to set a return value for state \"" + + getSubject().getKey().getID() + "\"", + e); + } + } + /* */ + } catch (final Exception e) { + LOGGER.warn("failed to execute Jython code for task " + getSubject().getKey().getID(), e); + throw new StateMachineException("failed to execute Jython code for task " + getSubject().getKey().getID(), + e); + } + + // Do the execution post work + executePost(returnValue); + + // Send back the return event + if (returnValue) { + return getOutgoing(); + } else { + return null; + } + } + + /** + * Cleans up the task after processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void cleanUp() throws StateMachineException { + interpreter.cleanup(); + LOGGER.debug("cleanUp:" + getSubject().getKey().getID() + "," + getSubject().getTaskLogic().getLogicFlavour() + + "," + getSubject().getTaskLogic().getLogic()); + } +} diff --git a/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskSelectExecutor.java b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskSelectExecutor.java new file mode 100644 index 000000000..cf94793ff --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/JythonTaskSelectExecutor.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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.jython; + +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; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.python.core.Py; +import org.python.core.PyCode; +import org.python.core.PyException; +import org.python.util.PythonInterpreter; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class JythonTaskSelectExecutor is the task selection executor for task selection logic written in Jython It is + * unlikely that this is thread safe. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JythonTaskSelectExecutor extends TaskSelectExecutor { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(JythonTaskSelectExecutor.class); + + // The Jython interpreter + private final PythonInterpreter interpreter = new PythonInterpreter(); + private PyCode compiled = null; + + /** + * Prepares the task for processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void prepare() throws StateMachineException { + interpreter.setErr(System.err); + interpreter.setOut(System.out); + + // Call generic prepare logic + super.prepare(); + try { + synchronized (Py.class) { + compiled = Py.compile_flags(getSubject().getTaskSelectionLogic().getLogic(), + "<" + getSubject().getKey().toString() + ">", "exec", null); + } + } catch (final PyException e) { + LOGGER.warn("failed to compile Jython code for task selection logic in " + getSubject().getKey().getID(), + e); + throw new StateMachineException( + "failed to compile Jython code for task selection logic in " + getSubject().getKey().getID(), e); + } + + } + + /** + * Executes the executor for the task in a sequential manner. + * + * @param executionID the execution ID for the current APEX policy execution + * @param incomingEvent the incoming event + * @return The outgoing event + * @throws StateMachineException on an execution error + * @throws ContextException on context errors + */ + @Override + public AxArtifactKey execute(final long executionID, final EnEvent incomingEvent) + throws StateMachineException, ContextException { + + boolean returnValue = false; + + // Do execution pre work + executePre(executionID, incomingEvent); + + try { + // Check and execute the Jython logic + /* Precompiled Version */ + synchronized (Py.class) { + // Set up the Jython engine + interpreter.set("executor", getExecutionContext()); + interpreter.exec(compiled); + + try { + final Object ret = interpreter.get("returnValue", java.lang.Boolean.class); + if (ret == null) { + LOGGER.error("execute: task selection logic failed to set a return value for state \"" + + getSubject().getKey().getID() + "\""); + throw new StateMachineException( + "execute: task selection logic failed to set a return value for state \"" + + getSubject().getKey().getID() + "\""); + } + returnValue = (Boolean) ret; + } catch (NullPointerException | ClassCastException e) { + LOGGER.error("execute: task selection logic failed to set a correct return value for state \"" + + getSubject().getKey().getID() + "\"", e); + throw new StateMachineException( + "execute: task selection logic failed to set a return value for state \"" + + getSubject().getKey().getID() + "\"", + e); + } + } + /* */ + } catch (final Exception e) { + LOGGER.warn("failed to execute Jython code for task selection logic in " + getSubject().getKey().getID(), + e); + throw new StateMachineException( + "failed to execute Jython code for task selection logic in " + getSubject().getKey().getID(), e); + } + + // Do the execution post work + executePost(returnValue); + + // Send back the return event + if (returnValue) { + return getOutgoing(); + } else { + return null; + } + } + + /** + * Cleans up the task after processing. + * + * @throws StateMachineException thrown when a state machine execution error occurs + */ + @Override + public void cleanUp() throws StateMachineException { + interpreter.cleanup(); + LOGGER.debug("cleanUp:" + getSubject().getKey().getID() + "," + + getSubject().getTaskSelectionLogic().getLogicFlavour() + "," + + getSubject().getTaskSelectionLogic().getLogic()); + } +} diff --git a/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/package-info.java b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/package-info.java new file mode 100644 index 000000000..f88ff75ef --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-jython/src/main/java/org/onap/policy/apex/plugins/executor/jython/package-info.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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========================================================= + */ + +/** + * Implements the Jython executor plugin for APEX, providing extensions of the abstract classes + * {@link org.onap.policy.apex.core.engine.executor.TaskExecutor}, + * {@link org.onap.policy.apex.core.engine.executor.TaskSelectExecutor}, and + * {@link org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor}. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + +package org.onap.policy.apex.plugins.executor.jython; -- cgit 1.2.3-korg