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.common.logging.flexlogger.FlexLogger;
28 import org.openecomp.policy.common.logging.flexlogger.Logger;
29 import org.openecomp.policy.drools.controller.DroolsController;
30 import org.openecomp.policy.drools.event.comm.Topic;
31 import org.openecomp.policy.drools.event.comm.TopicEndpoint;
32 import org.openecomp.policy.drools.event.comm.TopicListener;
33 import org.openecomp.policy.drools.event.comm.TopicSink;
34 import org.openecomp.policy.drools.event.comm.TopicSource;
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;
40 import com.fasterxml.jackson.annotation.JsonIgnore;
43 * This implementation of the Policy Controller merely aggregates and tracks for
44 * management purposes all underlying resources that this controller depends upon.
46 public class AggregatedPolicyController implements PolicyController,
52 private static Logger logger = FlexLogger.getLogger(AggregatedPolicyController.class);
55 * identifier for this policy controller
57 protected final String name;
60 * Abstracted Event Sources List regardless communication
63 protected final List<? extends TopicSource> sources;
66 * Abstracted Event Sinks List regardless communication
69 protected final List<? extends TopicSink> sinks;
72 * Mapping topics to sinks
75 protected final HashMap<String, TopicSink> topic2Sinks =
76 new HashMap<String, TopicSink>();
79 * Is this Policy Controller running (alive) ?
80 * reflects invocation of start()/stop() only
82 protected volatile boolean alive;
85 * Is this Policy Controller locked ?
86 * reflects if i/o controller related operations and start
88 * more specifically: start(), deliver() and onTopicEvent().
89 * It does not affect the ability to stop the
90 * underlying drools infrastructure
92 protected volatile boolean locked;
95 * Policy Drools Controller
97 protected volatile DroolsController droolsController;
100 * Properties used to initialize controller
102 protected final Properties properties;
105 * Constructor version mainly used for bootstrapping at initialization time
106 * a policy engine controller
108 * @param name controller name
111 * @throws IllegalArgumentException when invalid arguments are provided
113 public AggregatedPolicyController(String name, Properties properties)
114 throws IllegalArgumentException {
119 * 1. Register read topics with network infrastructure (ueb, dmaap, rest)
120 * 2. Register write topics with network infrastructure (ueb, dmaap, rest)
121 * 3. Register with drools infrastructure
124 // Create/Reuse Readers/Writers for all event sources endpoints
126 this.sources = TopicEndpoint.manager.addTopicSources(properties);
127 this.sinks = TopicEndpoint.manager.addTopicSinks(properties);
129 initDrools(properties);
132 /* persist new properties */
133 SystemPersistence.manager.storeController(name, properties);
134 this.properties = properties;
138 * initialize drools layer
139 * @throws IllegalArgumentException if invalid parameters are passed in
141 protected void initDrools(Properties properties) throws IllegalArgumentException {
143 // Register with drools infrastructure
144 this.droolsController = DroolsController.factory.build(properties, sources, sinks);
145 } catch (Exception | LinkageError e) {
146 logger.error("BUILD-INIT-DROOLS: " + e.getMessage());
149 // throw back exception as input properties cause problems
150 throw new IllegalArgumentException(e);
156 * @throws IllegalArgumentException if invalid parameters are passed in
158 protected void initSinks() throws IllegalArgumentException {
159 this.topic2Sinks.clear();
160 for (TopicSink sink: sinks) {
161 this.topic2Sinks.put(sink.getTopic(), sink);
169 public boolean updateDrools(DroolsConfiguration newDroolsConfiguration) {
171 DroolsConfiguration oldDroolsConfiguration =
172 new DroolsConfiguration(this.droolsController.getArtifactId(),
173 this.droolsController.getGroupId(),
174 this.droolsController.getVersion());
176 if (oldDroolsConfiguration.getGroupId().equalsIgnoreCase(newDroolsConfiguration.getGroupId()) &&
177 oldDroolsConfiguration.getArtifactId().equalsIgnoreCase(newDroolsConfiguration.getArtifactId()) &&
178 oldDroolsConfiguration.getVersion().equalsIgnoreCase(newDroolsConfiguration.getVersion())) {
179 logger.warn("UPDATE-DROOLS: nothing to do: identical configuration: " + oldDroolsConfiguration +
180 " <=> " + newDroolsConfiguration);
185 /* Drools Controller created, update initialization properties for restarts */
187 this.properties.setProperty(PolicyProperties.RULES_GROUPID, newDroolsConfiguration.getGroupId());
188 this.properties.setProperty(PolicyProperties.RULES_ARTIFACTID, newDroolsConfiguration.getArtifactId());
189 this.properties.setProperty(PolicyProperties.RULES_VERSION, newDroolsConfiguration.getVersion());
191 SystemPersistence.manager.storeController(name, this.properties);
193 this.initDrools(this.properties);
195 /* set drools controller to current locked status */
198 this.droolsController.lock();
200 this.droolsController.unlock();
202 /* set drools controller to current alive status */
205 this.droolsController.start();
207 this.droolsController.stop();
209 } catch (IllegalArgumentException e) {
210 logger.warn("INIT-DROOLS: " + e.getMessage());
222 public String getName() {
230 public boolean start() throws IllegalStateException {
231 if (logger.isInfoEnabled())
232 logger.info("START: " + this);
235 throw new IllegalStateException("Policy Controller " + name + " is locked");
244 boolean success = this.droolsController.start();
246 // register for events
248 for (TopicSource source: sources) {
249 source.register(this);
252 for (TopicSink sink: sinks) {
255 } catch (Exception e) {
256 logger.warn("can't start sink: " + sink + " because of " + e.getMessage());
268 public boolean stop() {
270 logger.info("STOP: " + this);
272 /* stop regardless locked state */
281 // 1. Stop registration
283 for (TopicSource source: sources) {
284 source.unregister(this);
287 boolean success = this.droolsController.stop();
295 public void shutdown() throws IllegalStateException {
296 if (logger.isInfoEnabled())
297 logger.info(this + "SHUTDOWN");
301 DroolsController.factory.shutdown(this.droolsController);
308 public void halt() throws IllegalStateException {
309 if (logger.isInfoEnabled())
310 logger.info(this + "HALT");
313 DroolsController.factory.destroy(this.droolsController);
314 SystemPersistence.manager.deleteController(this.name);
321 public void onTopicEvent(Topic.CommInfrastructure commType,
322 String topic, String event) {
324 logger.info("EVENT NOTIFICATION: " + commType + ":" + topic + ":" + event + " INTO " + this);
332 this.droolsController.offer(topic, event);
339 public boolean deliver(Topic.CommInfrastructure commType,
340 String topic, Object event)
341 throws IllegalArgumentException, IllegalStateException,
342 UnsupportedOperationException {
344 logger.info("DELIVER: " + commType + ":" + topic + ":" + event + " FROM " + this);
346 if (topic == null || topic.isEmpty())
347 throw new IllegalArgumentException("Invalid Topic");
350 throw new IllegalArgumentException("Invalid Event");
353 throw new IllegalStateException("Policy Engine is stopped");
356 throw new IllegalStateException("Policy Engine is locked");
358 if (!this.topic2Sinks.containsKey(topic)) {
359 logger.error("UNDELIVERED: " + commType + ":" + topic + ":" + event + " FROM " + this);
360 throw new IllegalArgumentException
361 ("Unsuported topic " + topic + " for delivery");
364 return this.droolsController.deliver
365 (this.topic2Sinks.get(topic), event);
372 public boolean isAlive() {
380 public boolean lock() {
381 logger.info("LOCK: " + this);
390 // it does not affect associated sources/sinks, they are
391 // autonomous entities
393 return this.droolsController.lock();
400 public boolean unlock() {
401 logger.info("UNLOCK: " + this);
410 return this.droolsController.unlock();
417 public boolean isLocked() {
425 public List<? extends TopicSource> getTopicSources() {
433 public List<? extends TopicSink> getTopicSinks() {
441 public DroolsController getDrools() {
442 return this.droolsController;
451 public Properties getProperties() {
452 return this.properties;
456 public String toString() {
457 StringBuilder builder = new StringBuilder();
458 builder.append("AggregatedPolicyController [name=").append(name).append(", alive=").append(alive).append(", locked=").append(locked)
459 .append(", droolsController=").append(droolsController).append("]");
460 return builder.toString();