2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.actorserviceprovider.impl;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.function.Function;
30 import org.onap.policy.controlloop.actorserviceprovider.Operator;
31 import org.onap.policy.controlloop.actorserviceprovider.Util;
32 import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
33 import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
34 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Implementation of an actor.
41 public class ActorImpl extends StartConfigPartial<Map<String, Object>> implements Actor {
42 private static final Logger logger = LoggerFactory.getLogger(ActorImpl.class);
45 * Maps a name to an operator.
47 private final Map<String, Operator> name2operator = new ConcurrentHashMap<>();
50 * Constructs the object.
52 * @param name actor name
54 public ActorImpl(String name) {
59 * This method simply returns {@code 0}.
62 public int getSequenceNumber() {
67 * Adds an operator supported by this actor.
69 * @param operator operation to be added
71 protected synchronized void addOperator(Operator operator) {
73 * This method is "synchronized" to prevent the state from changing while the
74 * operator is added. The map, itself, does not need synchronization as it's a
79 throw new IllegalStateException("attempt to set operators on a configured actor: " + getName());
82 name2operator.compute(operator.getName(), (opName, existingOp) -> {
83 if (existingOp == null) {
87 logger.warn("duplicate names for actor operation {}.{}: {}, ignoring {}", getName(), opName,
88 existingOp.getClass().getSimpleName(), operator.getClass().getSimpleName());
94 public String getName() {
99 public Operator getOperator(String name) {
100 Operator operator = name2operator.get(name);
101 if (operator == null) {
102 throw new IllegalArgumentException("unknown operator " + getName() + "." + name);
109 public Collection<Operator> getOperators() {
110 return name2operator.values();
114 public Set<String> getOperationNames() {
115 return name2operator.keySet();
119 * For each operation, it looks for a set of parameters by the same name and, if
120 * found, configures the operation with the parameters.
123 protected void doConfigure(Map<String, Object> parameters) {
124 final String actorName = getName();
125 logger.info("configuring operations for actor {}", actorName);
127 // function that creates operator-specific parameters, given the operation name
128 Function<String, Map<String, Object>> opParamsMaker = makeOperatorParameters(parameters);
130 for (Operator operator : name2operator.values()) {
131 String operName = operator.getName();
132 Map<String, Object> subparams = opParamsMaker.apply(operName);
134 if (subparams != null) {
137 operator.configure(subparams);
139 } catch (ParameterValidationRuntimeException e) {
140 logger.warn("failed to configure operation {}.{} because:\n{}", actorName, operName,
141 e.getResult().getResult(), e);
143 } catch (RuntimeException e) {
144 logger.warn("failed to configure operation {}.{}", actorName, operName, e);
147 } else if (operator.isConfigured()) {
148 logger.warn("missing configuration parameters for operation {}.{}; using previous parameters",
149 actorName, operName);
152 logger.warn("missing configuration parameters for operation {}.{}; operation cannot be started",
153 actorName, operName);
159 * Extracts the operator parameters from the actor parameters, for a given operator.
160 * This method translates the parameters to an {@link ActorParams} and then creates a function
161 * that will extract operator-specific parameters.
163 * @param actorParameters actor parameters
164 * @return a function to extract the operator parameters from the actor parameters.
165 * Note: this function may return {@code null} if there are no parameters for
166 * the given operation name
168 protected Function<String, Map<String, Object>> makeOperatorParameters(Map<String, Object> actorParameters) {
169 String actorName = getName();
172 return Util.translate(actorName, actorParameters, ActorParams.class)
173 .doValidation(actorName)
174 .makeOperationParameters(actorName);
179 * Starts each operation.
182 protected void doStart() {
183 final String actorName = getName();
184 logger.info("starting operations for actor {}", actorName);
186 for (Operator oper : name2operator.values()) {
187 if (oper.isConfigured()) {
188 Util.runFunction(oper::start, "failed to start operation {}.{}", actorName, oper.getName());
191 logger.warn("not starting unconfigured operation {}.{}", actorName, oper.getName());
197 * Stops each operation.
200 protected void doStop() {
201 final String actorName = getName();
202 logger.info("stopping operations for actor {}", actorName);
205 name2operator.values().forEach(
206 oper -> Util.runFunction(oper::stop, "failed to stop operation {}.{}", actorName, oper.getName()));
211 * Shuts down each operation.
214 protected void doShutdown() {
215 final String actorName = getName();
216 logger.info("shutting down operations for actor {}", actorName);
219 name2operator.values().forEach(oper -> Util.runFunction(oper::shutdown,
220 "failed to shutdown operation {}.{}", actorName, oper.getName()));
224 // TODO old code: remove lines down to **HERE**
227 public String actor() {
232 public List<String> recipes() {
233 return Collections.emptyList();
237 public List<String> recipeTargets(String recipe) {
238 return Collections.emptyList();
242 public List<String> recipePayloads(String recipe) {
243 return Collections.emptyList();