/* * ============LICENSE_START======================================================= * ONAP * ================================================================================ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ package org.onap.policy.controlloop; import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; import org.onap.policy.controlloop.CanonicalOnset; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.ControlLoopNotificationType; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager2Drools; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager2.NewEventStatus; import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager2; import org.onap.policy.controlloop.utils.ControlLoopUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.slf4j.LoggerFactory; import org.slf4j.Logger; import org.onap.policy.drools.system.PolicyEngineConstants; /* * * Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW. * */ rule "INSERT.PARAMS" when $params : ControlLoopParams() then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {} : TOSCA-POLICY=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." + drools.getRule().getName(), $params.getToscaPolicy()); end /* * * Called when a Tosca Policy is present. * */ rule "NEW.TOSCA.POLICY" when $policy : ToscaPolicy() then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: [{}|{}|{}|{}]: CONTENT: {}", drools.getRule().getName(), $policy.getType(), $policy.getTypeVersion(), $policy.getName(), $policy.getVersion(), $policy); ControlLoopParams params = ControlLoopUtils.toControlLoopParams($policy); if (params != null) { insert(params); } end /* * Remove Control Loop Parameters. */ rule "REMOVE.PARAMS" when $params : ControlLoopParams( $policyName : getPolicyName(), $policyVersion : getPolicyVersion() ) not ( ToscaPolicy( getName() == $policyName, getVersion() == $policyVersion ) ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: [{}|{}|{}]", drools.getRule().getName(), $params.getPolicyScope(), $params.getPolicyName(), $params.getPolicyVersion()); retract($params); end /* * * This rule responds to DCAE Events where there is no manager yet. Either it is * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled) * */ rule "EVENT" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : CanonicalOnset( closedLoopControlName == $clName ) not ( ControlLoopEventManager2Drools( closedLoopControlName == $event.getClosedLoopControlName(), getContext().getEvent() == $event ) ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}.{}: event={}", $clName, $params.getPolicyName(), drools.getRule().getName(), $event); // // Retract the event from memory; it will be managed by the manager for now on // retract($event); VirtualControlLoopNotification notification; try { // // Check the event, because we need it to not be null when // we create the ControlLoopEventManager2Drools. The ControlLoopEventManager2Drools // will do extra syntax checking as well as check if the closed loop is disabled. // if ($event.getRequestId() == null) { notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.REJECTED); notification.setFrom("policy"); notification.setMessage("Missing requestId"); notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); notification.setPolicyScope($params.getPolicyScope()); notification.setPolicyVersion($params.getPolicyVersion()); } else { ControlLoopEventManager2Drools manager = new ControlLoopEventManager2Drools($params, $event, drools.getWorkingMemory()); insert(manager); try { manager.start(); } catch(Exception e) { retract(manager); throw e; } notification = manager.makeNotification(); notification.setNotification(ControlLoopNotificationType.ACTIVE); notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); } } catch (Exception e) { logger.warn("{}: {}.{}", $clName, $params.getPolicyName(), drools.getRule().getName(), e); notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.REJECTED); notification.setMessage("Exception occurred: " + e.getMessage()); notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); notification.setPolicyScope($params.getPolicyScope()); notification.setPolicyVersion($params.getPolicyVersion()); } // // Generate notification // try { PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); } catch(RuntimeException e) { logger.warn("{}: {}.{}: event={} exception generating notification", $clName, $params.getPolicyName(), drools.getRule().getName(), $event, e); } end /* * * This rule happens when we get a subsequent event. * */ rule "EVENT.MANAGER.NEW.EVENT" when $event : VirtualControlLoopEvent( ) $manager : ControlLoopEventManager2Drools( closedLoopControlName == $event.getClosedLoopControlName(), getContext().getEvent() == $event ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}.{}: event={} manager={}", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $event, $manager); // // Remove the event from memory // retract($event); // // Check what kind of event this is // switch($manager.onNewEvent($event)) { case SYNTAX_ERROR: // // Ignore any bad syntax events // logger.warn("{}: {}.{}: syntax error", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName()); break; case FIRST_ABATEMENT: case SUBSEQUENT_ABATEMENT: // // TODO: handle the abatement. Currently, it's just discarded. // logger.info("{}: {}.{}: abatement", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName()); break; case FIRST_ONSET: case SUBSEQUENT_ONSET: default: // // We don't care about subsequent onsets // logger.warn("{}: {}.{}: subsequent onset", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName()); break; } end /* * * Step completed * */ rule "EVENT.MANAGER.PROCESSING" when $manager : ControlLoopEventManager2Drools( isUpdated(), isActive(), $notification : getNotification() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}.{}: manager={}", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $manager); // // Generate notification // try { $notification.setPolicyName($manager.getPolicyName() + "." + drools.getRule().getName()); PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", $notification); } catch(RuntimeException e) { logger.warn("{}: {}.{}: manager={} exception generating notification", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $manager, e); } // // Generate Response notification // try { ControlLoopResponse clResponse = $manager.getControlLoopResponse(); if (clResponse != null) { PolicyEngineConstants.getManager().deliver("DCAE_CL_RSP", clResponse); } } catch(RuntimeException e) { logger.warn("{}: {}.{}: manager={} exception generating Response notification", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $manager, e); } // // Discard this message and wait for the next response. // $manager.nextStep(); update($manager); end /* * * Final step completed * */ rule "EVENT.MANAGER.FINAL" when $manager : ControlLoopEventManager2Drools( !isActive(), $notification : getNotification() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}.{}: manager={}", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $manager); // // Generate notification // try { $notification.setPolicyName($manager.getPolicyName() + "." + drools.getRule().getName()); PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", $notification); } catch(RuntimeException e) { logger.warn("{}: {}.{}: manager={} exception generating notification", $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), $manager, e); } // // Retract and destroy the manager // retract($manager); $manager.destroy(); end /* * * This rule will clean up any rogue events where there is no * ControlLoopParams object corresponding to the onset event. * */ rule "EVENT.CLEANUP" salience -1 when $event : VirtualControlLoopEvent( $clName: closedLoopControlName ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, drools.getRule().getName()); logger.debug("{}: {}: orphan event={}", $clName, drools.getRule().getName(), $event); // // Retract the event // retract($event); end /* * * At this point, it appears that if we prevent the rules from getting messages from * topics, then that will also prevent the actors from getting them. So the following * rules are here just to discard those messages. * * These have a higher salience so the objects are removed before the "FINAL" message * is processed, so that the junit test can assume things are done once they see the * "FINAL" message. Otherwise, tests might fail sporadically. * */ rule "APPC.Response.CLEANUP" salience 1 when $msg : org.onap.policy.appc.Response( ) then retract($msg); end rule "APPC.Request.CLEANUP" salience 1 when $msg : org.onap.policy.appc.Request( ) then retract($msg); end rule "APPC-LCM.Response.CLEANUP" salience 1 when $msg : org.onap.policy.appclcm.AppcLcmDmaapWrapper( ) then retract($msg); end rule "SDNR.Response.CLEANUP" salience 1 when $msg : org.onap.policy.sdnr.PciResponseWrapper( ) then retract($msg); end