import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
+import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
-import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.controlloop.actorserviceprovider.impl.StartConfigPartial;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
* {@link #start()} to start all of the actors. When finished using the actor service,
* invoke {@link #stop()} or {@link #shutdown()}.
*/
-public class ActorService extends StartConfigPartial<Map<String, Map<String, Object>>> {
+public class ActorService extends StartConfigPartial<Map<String, Object>> {
private static final Logger logger = LoggerFactory.getLogger(ActorService.class);
private final Map<String, Actor> name2actor;
- private static class LazyHolder {
- static final ActorService INSTANCE = new ActorService();
- }
-
/**
* Constructs the object and loads the list of actors.
*/
- protected ActorService() {
+ public ActorService() {
super("actors");
Map<String, Actor> map = new HashMap<>();
- for (Actor newActor : loadActors()) {
+ for (Actor newActor : buildList()) {
map.compute(newActor.getName(), (name, existingActor) -> {
if (existingActor == null) {
return newActor;
}
/**
- * Get the single instance.
+ * Builds the list of actors, discarding those that cannot be constructed.
*
- * @return the instance
+ * @return the list of actors, sorted by ascending sequence number
*/
- public static ActorService getInstance() {
- return LazyHolder.INSTANCE;
+ private List<Actor> buildList() {
+ List<Actor> actors = new LinkedList<>();
+
+ Iterator<Actor> iter = loadActors().iterator();
+ while (iter.hasNext()) {
+ try {
+ actors.add(iter.next());
+ } catch (ServiceConfigurationError e) {
+ logger.warn("unable to load actor", e);
+ }
+ }
+
+ actors.sort((actor1, actor2) -> {
+ int cmp = Integer.compare(actor1.getSequenceNumber(), actor2.getSequenceNumber());
+ if (cmp != 0) {
+ return cmp;
+ }
+
+ return actor1.getClass().getName().compareTo(actor2.getClass().getName());
+ });
+
+ return actors;
}
/**
}
@Override
- protected void doConfigure(Map<String, Map<String, Object>> parameters) {
+ protected void doConfigure(Map<String, Object> parameters) {
logger.info("configuring actors");
- BeanValidationResult valres = new BeanValidationResult("ActorService", parameters);
-
for (Actor actor : name2actor.values()) {
String actorName = actor.getName();
- Map<String, Object> subparams = parameters.get(actorName);
+ Object paramValue = parameters.get(actorName);
- if (subparams != null) {
+ if (paramValue instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> subparams = (Map<String, Object>) paramValue;
try {
actor.configure(subparams);
} catch (ParameterValidationRuntimeException e) {
- logger.warn("failed to configure actor {}", actorName, e);
- valres.addResult(e.getResult());
+ logger.warn("failed to configure actor {} because:\n{}", actorName, e.getResult().getResult(), e);
} catch (RuntimeException e) {
logger.warn("failed to configure actor {}", actorName, e);
logger.warn("missing configuration parameters for actor {}; actor cannot be started", actorName);
}
}
-
- if (!valres.isValid() && logger.isWarnEnabled()) {
- logger.warn("actor services validation errors:\n{}", valres.getResult());
- }
}
@Override
@Override
protected void doStop() {
logger.info("stopping actors");
- name2actor.values()
- .forEach(actor -> Util.runFunction(actor::stop, "failed to stop actor {}", actor.getName()));
+ name2actor.values().forEach(actor -> Util.runFunction(actor::stop, "failed to stop actor {}", actor.getName()));
}
@Override