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.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
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.features.PolicyControllerFeatureAPI;
36 import org.openecomp.policy.drools.persistence.SystemPersistence;
37 import org.openecomp.policy.drools.properties.PolicyProperties;
38 import org.openecomp.policy.drools.protocol.configuration.DroolsConfiguration;
39 import org.openecomp.policy.drools.system.PolicyController;
41 import com.fasterxml.jackson.annotation.JsonIgnore;
44 * This implementation of the Policy Controller merely aggregates and tracks for
45 * management purposes all underlying resources that this controller depends upon.
47 public class AggregatedPolicyController implements PolicyController,
53 private static Logger logger = LoggerFactory.getLogger(AggregatedPolicyController.class);
56 * identifier for this policy controller
58 protected final String name;
61 * Abstracted Event Sources List regardless communication
64 protected final List<? extends TopicSource> sources;
67 * Abstracted Event Sinks List regardless communication
70 protected final List<? extends TopicSink> sinks;
73 * Mapping topics to sinks
76 protected final HashMap<String, TopicSink> topic2Sinks =
77 new HashMap<String, TopicSink>();
80 * Is this Policy Controller running (alive) ?
81 * reflects invocation of start()/stop() only
83 protected volatile boolean alive;
86 * Is this Policy Controller locked ?
87 * reflects if i/o controller related operations and start
89 * more specifically: start(), deliver() and onTopicEvent().
90 * It does not affect the ability to stop the
91 * underlying drools infrastructure
93 protected volatile boolean locked;
96 * Policy Drools Controller
98 protected volatile DroolsController droolsController;
101 * Properties used to initialize controller
103 protected final Properties properties;
106 * Constructor version mainly used for bootstrapping at initialization time
107 * a policy engine controller
109 * @param name controller name
112 * @throws IllegalArgumentException when invalid arguments are provided
114 public AggregatedPolicyController(String name, Properties properties)
115 throws IllegalArgumentException {
120 * 1. Register read topics with network infrastructure (ueb, dmaap, rest)
121 * 2. Register write topics with network infrastructure (ueb, dmaap, rest)
122 * 3. Register with drools infrastructure
125 // Create/Reuse Readers/Writers for all event sources endpoints
127 this.sources = TopicEndpoint.manager.addTopicSources(properties);
128 this.sinks = TopicEndpoint.manager.addTopicSinks(properties);
130 initDrools(properties);
133 /* persist new properties */
134 SystemPersistence.manager.storeController(name, properties);
135 this.properties = properties;
139 * initialize drools layer
140 * @throws IllegalArgumentException if invalid parameters are passed in
142 protected void initDrools(Properties properties) throws IllegalArgumentException {
144 // Register with drools infrastructure
145 this.droolsController = DroolsController.factory.build(properties, sources, sinks);
146 } catch (Exception | LinkageError e) {
147 logger.error("{}: cannot init-drools because of {}", this, e.getMessage(), e);
148 throw new IllegalArgumentException(e);
154 * @throws IllegalArgumentException if invalid parameters are passed in
156 protected void initSinks() throws IllegalArgumentException {
157 this.topic2Sinks.clear();
158 for (TopicSink sink: sinks) {
159 this.topic2Sinks.put(sink.getTopic(), sink);
167 public boolean updateDrools(DroolsConfiguration newDroolsConfiguration) {
169 DroolsConfiguration oldDroolsConfiguration =
170 new DroolsConfiguration(this.droolsController.getArtifactId(),
171 this.droolsController.getGroupId(),
172 this.droolsController.getVersion());
174 if (oldDroolsConfiguration.getGroupId().equalsIgnoreCase(newDroolsConfiguration.getGroupId()) &&
175 oldDroolsConfiguration.getArtifactId().equalsIgnoreCase(newDroolsConfiguration.getArtifactId()) &&
176 oldDroolsConfiguration.getVersion().equalsIgnoreCase(newDroolsConfiguration.getVersion())) {
177 logger.warn("{}: cannot update-drools: identical configuration {} vs {}",
178 this, oldDroolsConfiguration, newDroolsConfiguration);
183 /* Drools Controller created, update initialization properties for restarts */
185 this.properties.setProperty(PolicyProperties.RULES_GROUPID, newDroolsConfiguration.getGroupId());
186 this.properties.setProperty(PolicyProperties.RULES_ARTIFACTID, newDroolsConfiguration.getArtifactId());
187 this.properties.setProperty(PolicyProperties.RULES_VERSION, newDroolsConfiguration.getVersion());
189 SystemPersistence.manager.storeController(name, this.properties);
191 this.initDrools(this.properties);
193 /* set drools controller to current locked status */
196 this.droolsController.lock();
198 this.droolsController.unlock();
200 /* set drools controller to current alive status */
203 this.droolsController.start();
205 this.droolsController.stop();
207 } catch (IllegalArgumentException e) {
208 logger.error("{}: cannot update-drools because of {}", this, e.getMessage(), e);
219 public String getName() {
227 public boolean start() throws IllegalStateException {
228 logger.info("{}: start", this);
230 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
232 if (feature.beforeStart(this))
234 } catch (Exception e) {
235 logger.error("{}: feature {} before-start failure because of {}",
236 this, feature.getClass().getName(), e.getMessage(), e);
241 throw new IllegalStateException("Policy Controller " + name + " is locked");
250 boolean success = this.droolsController.start();
252 // register for events
254 for (TopicSource source: sources) {
255 source.register(this);
258 for (TopicSink sink: sinks) {
261 } catch (Exception e) {
262 logger.error("{}: cannot start {} because of {}",
263 this, sink, e.getMessage(), e);
267 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
269 if (feature.afterStart(this))
271 } catch (Exception e) {
272 logger.error("{}: feature {} after-start failure because of {}",
273 this, feature.getClass().getName(), e.getMessage(), e);
284 public boolean stop() {
285 logger.info("{}: stop", this);
287 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
289 if (feature.beforeStop(this))
291 } catch (Exception e) {
292 logger.error("{}: feature {} before-stop failure because of {}",
293 this, feature.getClass().getName(), e.getMessage(), e);
297 /* stop regardless locked state */
306 // 1. Stop registration
308 for (TopicSource source: sources) {
309 source.unregister(this);
312 boolean success = this.droolsController.stop();
314 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
316 if (feature.afterStop(this))
318 } catch (Exception e) {
319 logger.error("{}: feature {} after-stop failure because of {}",
320 this, feature.getClass().getName(), e.getMessage(), e);
331 public void shutdown() throws IllegalStateException {
332 logger.info("{}: shutdown", this);
334 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
336 if (feature.beforeShutdown(this))
338 } catch (Exception e) {
339 logger.error("{}: feature {} before-shutdown failure because of {}",
340 this, feature.getClass().getName(), e.getMessage(), e);
346 DroolsController.factory.shutdown(this.droolsController);
348 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
350 if (feature.afterShutdown(this))
352 } catch (Exception e) {
353 logger.error("{}: feature {} after-shutdown failure because of {}",
354 this, feature.getClass().getName(), e.getMessage(), e);
363 public void halt() throws IllegalStateException {
364 logger.info("{}: halt", this);
366 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
368 if (feature.beforeHalt(this))
370 } catch (Exception e) {
371 logger.error("{}: feature {} before-halt failure because of {}",
372 this, feature.getClass().getName(), e.getMessage(), e);
377 DroolsController.factory.destroy(this.droolsController);
378 SystemPersistence.manager.deleteController(this.name);
380 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
382 if (feature.afterHalt(this))
384 } catch (Exception e) {
385 logger.error("{}: feature {} after-halt failure because of {}",
386 this, feature.getClass().getName(), e.getMessage(), e);
395 public void onTopicEvent(Topic.CommInfrastructure commType,
396 String topic, String event) {
398 if (logger.isDebugEnabled())
399 logger.debug("{}: event offered from {}:{}: {}", this, commType, topic, event);
401 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
403 if (feature.beforeOffer(this, commType, topic, event))
405 } catch (Exception e) {
406 logger.error("{}: feature {} before-offer failure because of {}",
407 this, feature.getClass().getName(), e.getMessage(), e);
417 boolean success = this.droolsController.offer(topic, event);
419 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
421 if (feature.afterOffer(this, commType, topic, event, success))
423 } catch (Exception e) {
424 logger.error("{}: feature {} after-offer failure because of {}",
425 this, feature.getClass().getName(), e.getMessage(), e);
434 public boolean deliver(Topic.CommInfrastructure commType,
435 String topic, Object event)
436 throws IllegalArgumentException, IllegalStateException,
437 UnsupportedOperationException {
439 if (logger.isDebugEnabled())
440 logger.debug("{}: deliver event to {}:{}: {}", this, commType, topic, event);
442 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
444 if (feature.beforeDeliver(this, commType, topic, event))
446 } catch (Exception e) {
447 logger.error("{}: feature {} before-deliver failure because of {}",
448 this, feature.getClass().getName(), e.getMessage(), e);
452 if (topic == null || topic.isEmpty())
453 throw new IllegalArgumentException("Invalid Topic");
456 throw new IllegalArgumentException("Invalid Event");
459 throw new IllegalStateException("Policy Engine is stopped");
462 throw new IllegalStateException("Policy Engine is locked");
464 if (!this.topic2Sinks.containsKey(topic)) {
465 logger.warn("{}: cannot deliver event because the sink {}:{} is not registered: {}",
466 this, commType, topic, event);
467 throw new IllegalArgumentException("Unsuported topic " + topic + " for delivery");
470 boolean success = this.droolsController.deliver(this.topic2Sinks.get(topic), event);
472 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
474 if (feature.afterDeliver(this, commType, topic, event, success))
476 } catch (Exception e) {
477 logger.error("{}: feature {} after-deliver failure because of {}",
478 this, feature.getClass().getName(), e.getMessage(), e);
489 public boolean isAlive() {
497 public boolean lock() {
498 logger.info("{}: lock", this);
500 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
502 if (feature.beforeLock(this))
504 } catch (Exception e) {
505 logger.error("{}: feature {} before-lock failure because of {}",
506 this, feature.getClass().getName(), e.getMessage(), e);
517 // it does not affect associated sources/sinks, they are
518 // autonomous entities
520 boolean success = this.droolsController.lock();
522 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
524 if (feature.afterLock(this))
526 } catch (Exception e) {
527 logger.error("{}: feature {} after-lock failure because of {}",
528 this, feature.getClass().getName(), e.getMessage(), e);
539 public boolean unlock() {
541 logger.info("{}: unlock", this);
543 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
545 if (feature.beforeUnlock(this))
547 } catch (Exception e) {
548 logger.error("{}: feature {} before-unlock failure because of {}",
549 this, feature.getClass().getName(), e.getMessage(), e);
560 boolean success = this.droolsController.unlock();
562 for (PolicyControllerFeatureAPI feature : PolicyControllerFeatureAPI.providers.getList()) {
564 if (feature.afterUnlock(this))
566 } catch (Exception e) {
567 logger.error("{}: feature {} after-unlock failure because of {}",
568 this, feature.getClass().getName(), e.getMessage(), e);
579 public boolean isLocked() {
587 public List<? extends TopicSource> getTopicSources() {
595 public List<? extends TopicSink> getTopicSinks() {
603 public DroolsController getDrools() {
604 return this.droolsController;
613 public Properties getProperties() {
614 return this.properties;
618 public String toString() {
619 StringBuilder builder = new StringBuilder();
620 builder.append("AggregatedPolicyController [name=").append(name).append(", alive=").append(alive).append(", locked=").append(locked)
621 .append(", droolsController=").append(droolsController).append("]");
622 return builder.toString();