2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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.openecomp.policy.drools.system.internal;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Properties;
27 import org.openecomp.policy.drools.controller.DroolsController;
28 import org.openecomp.policy.drools.event.comm.Topic;
29 import org.openecomp.policy.drools.event.comm.TopicEndpoint;
30 import org.openecomp.policy.drools.event.comm.TopicListener;
31 import org.openecomp.policy.drools.event.comm.TopicSink;
32 import org.openecomp.policy.drools.event.comm.TopicSource;
33 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
34 import org.openecomp.policy.common.logging.flexlogger.Logger;
35 import org.openecomp.policy.drools.persistence.SystemPersistence;
36 import org.openecomp.policy.drools.properties.PolicyProperties;
37 import org.openecomp.policy.drools.protocol.configuration.DroolsConfiguration;
38 import org.openecomp.policy.drools.system.PolicyController;
39 import com.fasterxml.jackson.annotation.JsonIgnore;
42 * This implementation of the Policy Controller merely aggregates and tracks for
43 * management purposes all underlying resources that this controller depends upon.
45 public class AggregatedPolicyController implements PolicyController,
51 private static Logger logger = FlexLogger.getLogger(AggregatedPolicyController.class);
54 * identifier for this policy controller
56 protected final String name;
59 * Abstracted Event Sources List regardless communication
62 protected final List<? extends TopicSource> sources;
65 * Abstracted Event Sinks List regardless communication
68 protected final List<? extends TopicSink> sinks;
71 * Mapping topics to sinks
74 protected final HashMap<String, TopicSink> topic2Sinks =
75 new HashMap<String, TopicSink>();
78 * Is this Policy Controller running (alive) ?
79 * reflects invocation of start()/stop() only
81 protected volatile boolean alive;
84 * Is this Policy Controller locked ?
85 * reflects if i/o controller related operations and start
87 * more specifically: start(), deliver() and onTopicEvent().
88 * It does not affect the ability to stop the
89 * underlying drools infrastructure
91 protected volatile boolean locked;
94 * Policy Drools Controller
96 protected volatile DroolsController droolsController;
99 * Properties used to initialize controller
101 protected final Properties properties;
104 * Constructor version mainly used for bootstrapping at initialization time
105 * a policy engine controller
107 * @param name controller name
110 * @throws IllegalArgumentException when invalid arguments are provided
112 public AggregatedPolicyController(String name, Properties properties)
113 throws IllegalArgumentException {
118 * 1. Register read topics with network infrastructure (ueb, dmaap, rest)
119 * 2. Register write topics with network infrastructure (ueb, dmaap, rest)
120 * 3. Register with drools infrastructure
123 // Create/Reuse Readers/Writers for all event sources endpoints
125 this.sources = TopicEndpoint.manager.addTopicSources(properties);
126 this.sinks = TopicEndpoint.manager.addTopicSinks(properties);
128 initDrools(properties);
131 /* persist new properties */
132 SystemPersistence.manager.storeController(name, properties);
133 this.properties = properties;
137 * initialize drools layer
138 * @throws IllegalArgumentException if invalid parameters are passed in
140 protected void initDrools(Properties properties) throws IllegalArgumentException {
142 // Register with drools infrastructure
143 this.droolsController = DroolsController.factory.build(properties, sources, sinks);
144 } catch (Exception | LinkageError e) {
145 logger.error("BUILD-INIT-DROOLS: " + e.getMessage());
148 // throw back exception as input properties cause problems
149 throw new IllegalArgumentException(e);
155 * @throws IllegalArgumentException if invalid parameters are passed in
157 protected void initSinks() throws IllegalArgumentException {
158 this.topic2Sinks.clear();
159 for (TopicSink sink: sinks) {
160 this.topic2Sinks.put(sink.getTopic(), sink);
168 public boolean updateDrools(DroolsConfiguration newDroolsConfiguration) {
170 DroolsConfiguration oldDroolsConfiguration =
171 new DroolsConfiguration(this.droolsController.getArtifactId(),
172 this.droolsController.getGroupId(),
173 this.droolsController.getVersion());
175 if (oldDroolsConfiguration.getGroupId().equalsIgnoreCase(newDroolsConfiguration.getGroupId()) &&
176 oldDroolsConfiguration.getArtifactId().equalsIgnoreCase(newDroolsConfiguration.getArtifactId()) &&
177 oldDroolsConfiguration.getVersion().equalsIgnoreCase(newDroolsConfiguration.getVersion())) {
178 logger.warn("UPDATE-DROOLS: nothing to do: identical configuration: " + oldDroolsConfiguration +
179 " <=> " + newDroolsConfiguration);
184 /* Drools Controller created, update initialization properties for restarts */
186 this.properties.setProperty(PolicyProperties.RULES_GROUPID, newDroolsConfiguration.getGroupId());
187 this.properties.setProperty(PolicyProperties.RULES_ARTIFACTID, newDroolsConfiguration.getArtifactId());
188 this.properties.setProperty(PolicyProperties.RULES_VERSION, newDroolsConfiguration.getVersion());
190 SystemPersistence.manager.storeController(name, this.properties);
192 this.initDrools(this.properties);
194 /* set drools controller to current locked status */
197 this.droolsController.lock();
199 this.droolsController.unlock();
201 /* set drools controller to current alive status */
204 this.droolsController.start();
206 this.droolsController.stop();
208 } catch (IllegalArgumentException e) {
209 logger.warn("INIT-DROOLS: " + e.getMessage());
221 public String getName() {
229 public boolean start() throws IllegalStateException {
230 if (logger.isInfoEnabled())
231 logger.info("START: " + this);
234 throw new IllegalStateException("Policy Controller " + name + " is locked");
243 boolean success = this.droolsController.start();
245 // register for events
247 for (TopicSource source: sources) {
248 source.register(this);
251 for (TopicSink sink: sinks) {
254 } catch (Exception e) {
255 logger.warn("can't start sink: " + sink + " because of " + e.getMessage());
267 public boolean stop() {
269 logger.info("STOP: " + this);
271 /* stop regardless locked state */
280 // 1. Stop registration
282 for (TopicSource source: sources) {
283 source.unregister(this);
286 boolean success = this.droolsController.stop();
294 public void shutdown() throws IllegalStateException {
295 if (logger.isInfoEnabled())
296 logger.info(this + "SHUTDOWN");
300 DroolsController.factory.shutdown(this.droolsController);
307 public void halt() throws IllegalStateException {
308 if (logger.isInfoEnabled())
309 logger.info(this + "HALT");
312 DroolsController.factory.destroy(this.droolsController);
313 SystemPersistence.manager.deleteController(this.name);
320 public void onTopicEvent(Topic.CommInfrastructure commType,
321 String topic, String event) {
323 logger.info("EVENT NOTIFICATION: " + commType + ":" + topic + ":" + event + " INTO " + this);
331 this.droolsController.offer(topic, event);
338 public boolean deliver(Topic.CommInfrastructure commType,
339 String topic, Object event)
340 throws IllegalArgumentException, IllegalStateException,
341 UnsupportedOperationException {
343 logger.info("DELIVER: " + commType + ":" + topic + ":" + event + " FROM " + this);
345 if (topic == null || topic.isEmpty())
346 throw new IllegalArgumentException("Invalid Topic");
349 throw new IllegalArgumentException("Invalid Event");
352 throw new IllegalStateException("Policy Engine is stopped");
355 throw new IllegalStateException("Policy Engine is locked");
357 if (!this.topic2Sinks.containsKey(topic)) {
358 logger.error("UNDELIVERED: " + commType + ":" + topic + ":" + event + " FROM " + this);
359 throw new IllegalArgumentException
360 ("Unsuported topic " + topic + " for delivery");
363 return this.droolsController.deliver
364 (this.topic2Sinks.get(topic), event);
371 public boolean isAlive() {
379 public boolean lock() {
380 logger.info("LOCK: " + this);
389 // it does not affect associated sources/sinks, they are
390 // autonomous entities
392 return this.droolsController.lock();
399 public boolean unlock() {
400 logger.info("UNLOCK: " + this);
409 return this.droolsController.unlock();
416 public boolean isLocked() {
424 public List<? extends TopicSource> getTopicSources() {
432 public List<? extends TopicSink> getTopicSinks() {
440 public DroolsController getDrools() {
441 return this.droolsController;
445 public String toString() {
446 StringBuilder builder = new StringBuilder();
447 builder.append("AggregatedPolicyController [name=").append(name).append(", alive=").append(alive).append(", locked=").append(locked)
448 .append(", droolsController=").append(droolsController).append("]");
449 return builder.toString();
456 public Properties getInitializationProperties() {
457 return this.properties;