2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.core.engine.executor;
25 import java.util.Properties;
26 import java.util.TreeMap;
27 import org.onap.policy.apex.context.ContextException;
28 import org.onap.policy.apex.core.engine.ExecutorParameters;
29 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
30 import org.onap.policy.apex.core.engine.event.EnEvent;
31 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
32 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
33 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
34 import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
35 import org.onap.policy.apex.model.policymodel.concepts.AxState;
36 import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
39 * This class is the executor for a state machine built from a policy.
41 * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
42 * @author Liam Fallon (liam.fallon@ericsson.com)
44 public class StateMachineExecutor implements Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> {
45 // The Apex Policy and context for this state machine
46 private AxPolicy axPolicy = null;
47 private Executor<?, ?, ?, ?> parent = null;
48 private ApexInternalContext internalContext = null;
50 // The list of state executors for this state machine
51 private final Map<AxReferenceKey, StateExecutor> stateExecutorMap = new TreeMap<>();
54 private StateExecutor firstExecutor = null;
56 // The next state machine executor
57 private Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> nextExecutor = null;
59 // The executor factory
60 private ExecutorFactory executorFactory = null;
63 * Constructor, save the executor factory that will give us executors for task selection logic and task logic.
65 * @param executorFactory the executor factory
66 * @param owner the artifact key of the owner of this state machine
68 public StateMachineExecutor(final ExecutorFactory executorFactory, final AxArtifactKey owner) {
69 this.executorFactory = executorFactory;
76 public void setContext(final Executor<?, ?, ?, ?> newParent, final AxPolicy newAxPolicy,
77 final ApexInternalContext newInternalContext) {
78 // Save the policy and context for this state machine
79 this.parent = newParent;
80 this.axPolicy = newAxPolicy;
81 this.internalContext = newInternalContext;
83 // Clear the first executor, setContext can be called multiple times
86 // Create the state executors for this state machine
87 StateExecutor lastExecutor = null;
88 for (final AxState state : axPolicy.getStateMap().values()) {
89 // Create a state executor for this state and add its context (the state)
90 final StateExecutor stateExecutor = new StateExecutor(executorFactory);
91 stateExecutor.setContext(this, state, internalContext);
93 // Update the next executor on the last executor
94 if (lastExecutor != null) {
95 lastExecutor.setNext(stateExecutor);
97 lastExecutor = stateExecutor;
99 // Add the state executor to the executor list
100 stateExecutorMap.put(state.getKey(), stateExecutor);
102 // Set the first executor if it is not set
103 if (state.getKey().getLocalName().equals(axPolicy.getFirstState())) {
104 firstExecutor = stateExecutor;
113 public void prepare() throws StateMachineException {
114 for (final StateExecutor stateExecutor : stateExecutorMap.values()) {
115 stateExecutor.prepare();
123 public EnEvent execute(final long executionId, final Properties executionProperties, final EnEvent incomingEvent)
124 throws StateMachineException, ContextException {
125 // Check if there are any states on the state machine
126 if (stateExecutorMap.size() == 0) {
127 throw new StateMachineException("no states defined on state machine");
130 // Check if the first state of the machine is defined
131 if (firstExecutor == null) {
132 throw new StateMachineException("first state not defined on state machine");
135 // Get the first state of the state machine and define a state output that starts state
137 StateExecutor stateExecutor = firstExecutor;
138 StateOutput stateOutput = new StateOutput(new AxStateOutput(firstExecutor.getSubject().getKey(),
139 incomingEvent.getKey(), firstExecutor.getSubject().getKey()), incomingEvent);
142 // Execute the state, it returns an output or throws an exception
143 stateOutput = stateExecutor.execute(executionId, executionProperties, stateOutput.getOutputEvent());
145 // Use the next state of the state output to find if all the states have executed
146 if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
150 // Use the next state of the state output to find the next state
151 stateExecutor = stateExecutorMap.get(stateOutput.getNextState());
152 if (stateExecutor == null) {
153 throw new StateMachineException(
154 "state execution failed, next state \"" + stateOutput.getNextState().getId() + "\" not found");
158 return stateOutput.getOutputEvent();
165 public final void executePre(final long executionId, final Properties executionProperties,
166 final EnEvent incomingEntity) throws StateMachineException {
167 throw new StateMachineException("execution pre work not implemented on class");
174 public final void executePost(final boolean returnValue) throws StateMachineException {
175 throw new StateMachineException("execution post work not implemented on class");
182 public void cleanUp() throws StateMachineException {
183 for (final StateExecutor stateExecutor : stateExecutorMap.values()) {
184 stateExecutor.cleanUp();
192 public AxArtifactKey getKey() {
193 return axPolicy.getKey();
200 public final Executor<?, ?, ?, ?> getParent() {
208 public final AxPolicy getSubject() {
216 public final ApexInternalContext getContext() {
217 return internalContext;
224 public final EnEvent getIncoming() {
232 public final EnEvent getOutgoing() {
240 public final void setNext(final Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> newNextExecutor) {
241 this.nextExecutor = newNextExecutor;
248 public final Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> getNext() {
256 public void setParameters(final ExecutorParameters parameters) {
257 // Not implemented in this class