2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019-2020 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.impl;
25 import java.util.Map.Entry;
26 import java.util.TreeMap;
28 import org.onap.policy.apex.core.engine.EngineParameterConstants;
29 import org.onap.policy.apex.core.engine.EngineParameters;
30 import org.onap.policy.apex.core.engine.ExecutorParameters;
31 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
32 import org.onap.policy.apex.core.engine.executor.Executor;
33 import org.onap.policy.apex.core.engine.executor.ExecutorFactory;
34 import org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor;
35 import org.onap.policy.apex.core.engine.executor.TaskExecutor;
36 import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor;
37 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
38 import org.onap.policy.apex.core.engine.executor.exception.StateMachineRuntimeException;
39 import org.onap.policy.apex.model.policymodel.concepts.AxState;
40 import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
41 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
42 import org.onap.policy.common.parameters.ParameterService;
43 import org.onap.policy.common.utils.validation.Assertions;
44 import org.slf4j.ext.XLogger;
45 import org.slf4j.ext.XLoggerFactory;
48 * The Class ExecutorFactoryImpl is a factory class that returns task selection logic and task logic executors depending
49 * on the type of logic executor has been specified for the task selection logic in a state or task logic in a task.
51 * @author Liam Fallon (liam.fallon@ericsson.com)
53 public class ExecutorFactoryImpl implements ExecutorFactory {
54 // Get a reference to the logger
55 private static final XLogger LOGGER = XLoggerFactory.getXLogger(ExecutorFactoryImpl.class);
57 private final EngineParameters engineParameters;
58 // A map of logic flavours mapped to executor classes for plugins to executors for those logic flavours
59 private Map<String, Class<Executor<?, ?, ?, ?>>> taskExecutorPluginClassMap = new TreeMap<>();
60 private Map<String, Class<Executor<?, ?, ?, ?>>> taskSelectionExecutorPluginClassMap = new TreeMap<>();
61 private Map<String, Class<Executor<?, ?, ?, ?>>> stateFinalizerExecutorPluginClassMap = new TreeMap<>();
63 // A map of parameters for executors
64 private final Map<String, ExecutorParameters> implementationParameterMap = new TreeMap<>();
67 * Constructor, builds the class map for executors.
69 * @throws StateMachineException on plugin creation errors
71 public ExecutorFactoryImpl() throws StateMachineException {
72 engineParameters = ParameterService.get(EngineParameterConstants.MAIN_GROUP_NAME);
74 Assertions.argumentOfClassNotNull(engineParameters, StateMachineException.class,
75 "Parameter \"engineParameters\" may not be null");
77 // Instantiate each executor class map entry
78 for (final Entry<String, ExecutorParameters> executorParameterEntry : engineParameters.getExecutorParameterMap()
80 // Get classes for all types of executors for this logic type
81 taskExecutorPluginClassMap.put(executorParameterEntry.getKey(),
82 getExecutorPluginClass(executorParameterEntry.getValue().getTaskExecutorPluginClass()));
83 taskSelectionExecutorPluginClassMap.put(executorParameterEntry.getKey(),
84 getExecutorPluginClass(executorParameterEntry.getValue().getTaskSelectionExecutorPluginClass()));
85 stateFinalizerExecutorPluginClassMap.put(executorParameterEntry.getKey(),
86 getExecutorPluginClass(executorParameterEntry.getValue().getStateFinalizerExecutorPluginClass()));
88 // Save the executor implementation parameters
89 implementationParameterMap.put(executorParameterEntry.getKey(), executorParameterEntry.getValue());
97 public TaskSelectExecutor getTaskSelectionExecutor(final Executor<?, ?, ?, ?> parentExecutor, final AxState state,
98 final ApexInternalContext context) {
99 if (!state.checkSetTaskSelectionLogic()) {
103 // Create task selection executor
104 final TaskSelectExecutor tsExecutor =
105 (TaskSelectExecutor) createExecutor(state.getTaskSelectionLogic().getLogicFlavour(),
106 taskSelectionExecutorPluginClassMap.get(state.getTaskSelectionLogic().getLogicFlavour()),
107 TaskSelectExecutor.class);
108 tsExecutor.setParameters(implementationParameterMap.get(state.getTaskSelectionLogic().getLogicFlavour()));
109 tsExecutor.setContext(parentExecutor, state, context);
118 public TaskExecutor getTaskExecutor(final Executor<?, ?, ?, ?> parentExecutor, final AxTask task,
119 final ApexInternalContext context) {
120 // Create task executor
121 final TaskExecutor taskExecutor = (TaskExecutor) createExecutor(task.getTaskLogic().getLogicFlavour(),
122 taskExecutorPluginClassMap.get(task.getTaskLogic().getLogicFlavour()), TaskExecutor.class);
123 taskExecutor.setParameters(implementationParameterMap.get(task.getTaskLogic().getLogicFlavour()));
124 taskExecutor.setContext(parentExecutor, task, context);
125 taskExecutor.updateTaskParameters(engineParameters.getTaskParameters());
133 public StateFinalizerExecutor getStateFinalizerExecutor(final Executor<?, ?, ?, ?> parentExecutor,
134 final AxStateFinalizerLogic logic, final ApexInternalContext context) {
135 // Create state finalizer executor
136 final StateFinalizerExecutor sfExecutor = (StateFinalizerExecutor) createExecutor(logic.getLogicFlavour(),
137 stateFinalizerExecutorPluginClassMap.get(logic.getLogicFlavour()), StateFinalizerExecutor.class);
138 sfExecutor.setParameters(implementationParameterMap.get(logic.getLogicFlavour()));
139 sfExecutor.setContext(parentExecutor, logic, context);
145 * Get an executor class for a given executor plugin class name.
147 * @param executorClassName The name of the executor plugin class
148 * @return an executor class
149 * @throws StateMachineException on plugin instantiation errors
151 @SuppressWarnings("unchecked")
152 private Class<Executor<?, ?, ?, ?>> getExecutorPluginClass(final String executorClassName)
153 throws StateMachineException {
154 // It's OK for an executor class not to be defined as long as it's not called
155 if (executorClassName == null) {
159 // Get the class for the executor using reflection
160 Class<? extends Object> executorPluginClass = null;
162 executorPluginClass = Class.forName(executorClassName);
163 } catch (final ClassNotFoundException e) {
164 LOGGER.error("Apex executor class not found for executor plugin \"" + executorClassName + "\"", e);
165 throw new StateMachineException(
166 "Apex executor class not found for executor plugin \"" + executorClassName + "\"", e);
169 // Check the class is an executor
170 if (!Executor.class.isAssignableFrom(executorPluginClass)) {
171 LOGGER.error("Specified Apex executor plugin class \"{}\" does not implment the Executor interface",
173 throw new StateMachineException("Specified Apex executor plugin class \"" + executorClassName
174 + "\" does not implment the Executor interface");
177 return (Class<Executor<?, ?, ?, ?>>) executorPluginClass;
181 * Get an instance of an executor plugin class of the specified type and super type.
183 * @param logicFlavour The logic flavour of the logic
184 * @param executorClass The sub-class of the executor type to be instantiated
185 * @param executorSuperClass The super type of the class of executor to be instantiated
186 * @return The instantiated class
188 private Executor<?, ?, ?, ?> createExecutor(final String logicFlavour,
189 final Class<Executor<?, ?, ?, ?>> executorClass,
190 final Class<? extends Executor<?, ?, ?, ?>> executorSuperClass) {
191 // It's OK for an executor class not to be defined but it's not all right to try and create
194 if (executorClass == null) {
195 final String errorMessage = "Executor plugin class not defined for \"" + logicFlavour
196 + "\" executor of type \"" + executorSuperClass.getName() + "\"";
197 LOGGER.error(errorMessage);
198 throw new StateMachineRuntimeException(errorMessage);
201 // Create an executor for the specified logic flavour
202 Object executorObject = null;
204 executorObject = executorClass.getDeclaredConstructor().newInstance();
205 } catch (final Exception e) {
206 final String errorMessage = "Instantiation error on \"" + logicFlavour + "\" executor of type \""
207 + executorClass.getName() + "\"";
208 LOGGER.error(errorMessage, e);
209 throw new StateMachineRuntimeException(errorMessage, e);
212 // Check the class is the correct type of executor
213 if (!(executorSuperClass.isAssignableFrom(executorObject.getClass()))) {
214 final String errorMessage = "Executor on \"" + logicFlavour + "\" of type \"" + executorClass
215 + "\" is not an instance of \"" + executorSuperClass.getName() + "\"";
217 LOGGER.error(errorMessage);
218 throw new StateMachineRuntimeException(errorMessage);
221 return (Executor<?, ?, ?, ?>) executorObject;