2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018, 2020 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.controlloop.actorserviceprovider;
24 import com.google.common.collect.ImmutableMap;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.LinkedList;
29 import java.util.List;
31 import java.util.ServiceConfigurationError;
32 import java.util.ServiceLoader;
34 import org.onap.policy.common.parameters.BeanValidationResult;
35 import org.onap.policy.controlloop.actorserviceprovider.impl.StartConfigPartial;
36 import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
37 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * Service that manages a set of actors. To use the service, first invoke
43 * {@link #configure(Map)} to configure all of the actors, and then invoke
44 * {@link #start()} to start all of the actors. When finished using the actor service,
45 * invoke {@link #stop()} or {@link #shutdown()}.
47 public class ActorService extends StartConfigPartial<Map<String, Object>> {
48 private static final Logger logger = LoggerFactory.getLogger(ActorService.class);
50 private final Map<String, Actor> name2actor;
53 * Constructs the object and loads the list of actors.
55 public ActorService() {
58 Map<String, Actor> map = new HashMap<>();
60 for (Actor newActor : buildList()) {
61 map.compute(newActor.getName(), (name, existingActor) -> {
62 if (existingActor == null) {
66 logger.warn("duplicate actor names for {}: {}, ignoring {}", name,
67 existingActor.getClass().getSimpleName(), newActor.getClass().getSimpleName());
72 name2actor = ImmutableMap.copyOf(map);
76 * Builds the list of actors, discarding those that cannot be constructed.
78 * @return the list of actors, sorted by ascending sequence number
80 private List<Actor> buildList() {
81 List<Actor> actors = new LinkedList<>();
83 Iterator<Actor> iter = loadActors().iterator();
84 while (iter.hasNext()) {
86 actors.add(iter.next());
87 } catch (ServiceConfigurationError e) {
88 logger.warn("unable to load actor", e);
92 actors.sort((actor1, actor2) -> {
93 int cmp = Integer.compare(actor1.getSequenceNumber(), actor2.getSequenceNumber());
98 return actor1.getClass().getName().compareTo(actor2.getClass().getName());
105 * Gets a particular actor.
107 * @param name name of the actor of interest
108 * @return the desired actor
109 * @throws IllegalArgumentException if no actor by the given name exists
111 public Actor getActor(String name) {
112 Actor actor = name2actor.get(name);
114 throw new IllegalArgumentException("unknown actor " + name);
125 public Collection<Actor> getActors() {
126 return name2actor.values();
130 * Gets the names of the actors.
132 * @return the actor names
134 public Set<String> getActorNames() {
135 return name2actor.keySet();
139 protected void doConfigure(Map<String, Object> parameters) {
140 logger.info("configuring actors");
142 BeanValidationResult valres = new BeanValidationResult("ActorService", parameters);
144 for (Actor actor : name2actor.values()) {
145 String actorName = actor.getName();
146 Object paramValue = parameters.get(actorName);
148 if (paramValue instanceof Map) {
149 @SuppressWarnings("unchecked")
150 Map<String, Object> subparams = (Map<String, Object>) paramValue;
153 actor.configure(subparams);
155 } catch (ParameterValidationRuntimeException e) {
156 logger.warn("failed to configure actor {}", actorName, e);
157 valres.addResult(e.getResult());
159 } catch (RuntimeException e) {
160 logger.warn("failed to configure actor {}", actorName, e);
163 } else if (actor.isConfigured()) {
164 logger.warn("missing configuration parameters for actor {}; using previous parameters", actorName);
167 logger.warn("missing configuration parameters for actor {}; actor cannot be started", actorName);
171 if (!valres.isValid() && logger.isWarnEnabled()) {
172 logger.warn("actor services validation errors:\n{}", valres.getResult());
177 protected void doStart() {
178 logger.info("starting actors");
180 for (Actor actor : name2actor.values()) {
181 if (actor.isConfigured()) {
182 Util.runFunction(actor::start, "failed to start actor {}", actor.getName());
185 logger.warn("not starting unconfigured actor {}", actor.getName());
191 protected void doStop() {
192 logger.info("stopping actors");
193 name2actor.values().forEach(actor -> Util.runFunction(actor::stop, "failed to stop actor {}", actor.getName()));
197 protected void doShutdown() {
198 logger.info("shutting down actors");
201 name2actor.values().forEach(
202 actor -> Util.runFunction(actor::shutdown, "failed to shutdown actor {}", actor.getName()));
207 // the following methods may be overridden by junit tests
209 protected Iterable<Actor> loadActors() {
210 return ServiceLoader.load(Actor.class);