3 * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
4 * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
5 * ACCORDANCE WITH APPLICABLE AGREEMENTS.
7 * Copyright (c) 2016 AT&T Knowledge Ventures
8 * Unpublished and Not for Publication
11 package com.att.ecomp.policy.controlloop;
13 import com.att.ecomp.policy.controlloop.ATTControlLoopEvent;
14 import org.openecomp.policy.controlloop.VirtualControlLoopEvent;
15 import org.openecomp.policy.controlloop.VirtualControlLoopNotification;
16 import org.openecomp.policy.controlloop.ControlLoopEventStatus;
17 import com.att.ecomp.policy.controlloop.ATTControlLoopNotification;
18 import org.openecomp.policy.controlloop.ControlLoopNotificationType;
19 import com.att.ecomp.policy.controlloop.ControlLoopLogger;
20 import com.att.ecomp.policy.controlloop.policy.PolicyResult;
21 import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager;
22 import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
23 import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopOperationManager;
24 import org.openecomp.policy.appc.Request;
25 import org.openecomp.policy.appc.Response;
26 import org.openecomp.policy.appc.CommonHeader;
27 import com.att.ecomp.policy.guard.PolicyGuard;
28 import com.att.ecomp.policy.guard.PolicyGuard.LockResult;
29 import com.att.ecomp.policy.guard.TargetLock;
30 import com.att.ecomp.policy.guard.GuardResult;
31 import com.att.ecomp.policy.guard.PolicyGuardRequest;
32 import com.att.ecomp.policy.guard.PolicyGuardResponse;
33 import com.att.ecomp.policy.guard.PolicyGuardXacmlRequestAttributes;
34 import com.att.research.xacml.api.pdp.PDPEngine;
35 import com.att.research.xacml.std.annotations.RequestParser;
36 import com.att.ecomp.policy.guard.PolicyGuardXacmlHelper;
39 // REPLACE THESE WITH PRODUCTION VERSIONS
41 import com.att.ecomp.policy.controlloop.ControlLoopLogger;
42 import com.att.ecomp.policy.drools.PolicyEngine;
44 global ControlLoopLogger Logger;
45 global PolicyEngine Engine;
46 global PDPEngine XacmlPdpEngine;
48 import java.time.Instant;
49 import java.util.LinkedList;
50 import java.util.Iterator;
53 closedLoopControlName : String
54 controlLoopYaml : String
57 declare OperationTimer
58 closedLoopControlName : String
63 declare ControlLoopTimer
64 closedLoopControlName : String
72 * Called once and only once to insert the parameters into working memory for this Closed Loop policy.
75 rule "${policyName}.SETUP"
81 Logger.info("------------------------------------------------------------------------------------------------");
82 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
83 Params params = new Params();
84 params.setClosedLoopControlName("${closedLoopControlName}");
85 params.setControlLoopYaml("${controlLoopYaml}");
87 Logger.metrics("Inserted " + params);
88 Logger.info("------------------------------------------------------------------------------------------------");
93 * This rule responds to DCAE Events where there is no manager yet. Either it is
94 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
97 rule "${policyName}.EVENT"
99 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
100 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
101 not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
107 Logger.info("------------------------------------------------------------------------------------------------");
108 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
110 // Check the event, because we need it to not be null when
111 // we create the ControlLoopEventManager. The ControlLoopEventManager
112 // will do extra syntax checking as well check if the closed loop is disabled.
114 if ($event.requestID == null) {
115 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
116 notification.notification = ControlLoopNotificationType.REJECTED;
117 notification.from = "policy";
118 notification.message = "Missing requestID";
119 notification.policyName = drools.getRule().getName();
120 notification.policyScope = "${policyScope}";
121 notification.policyVersion = "${policyVersion}";
123 // Let interested parties know
125 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
127 // Retract it from memory
132 // Create an EventManager
134 ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
136 // Determine if EventManager can actively process the event (i.e. syntax, is_closed_loop_disabled checks etc.)
138 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
139 notification.from = "pdp-0001-controller=controlloop"; // Engine.getInstanceName()
140 notification.policyName = drools.getRule().getName();
141 notification.policyScope = "${policyScope}";
142 notification.policyVersion = "${policyVersion}";
144 // Are we actively pursuing this event?
146 if (notification.notification == ControlLoopNotificationType.ACTIVE) {
148 // Insert Event Manager into memory, this will now kick off processing.
152 // Let interested parties know
154 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
156 // Setup the Overall Control Loop timer
158 ControlLoopTimer clTimer = new ControlLoopTimer();
159 clTimer.setClosedLoopControlName($event.closedLoopControlName);
160 clTimer.setRequestID($event.requestID.toString());
161 clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
168 // Let interested parties know
170 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
172 // Retract it from memory
177 // Now that the manager is inserted into Drools working memory, we'll wait for
178 // another rule to fire in order to continue processing. This way we can also
179 // then screen for additional ONSET and ABATED events for this RequestID.
182 } catch (Exception e) {
184 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
185 notification.notification = ControlLoopNotificationType.REJECTED;
186 notification.message = "Exception occurred " + e.getMessage();
187 notification.policyName = drools.getRule().getName();
188 notification.policyScope = "${policyScope}";
189 notification.policyVersion = "${policyVersion}";
193 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
203 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
204 * is now created. We can start processing the yaml specification via the Event Manager.
207 rule "${policyName}.EVENT.MANAGER"
209 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
210 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
211 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
212 $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
217 Logger.info("------------------------------------------------------------------------------------------------");
218 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
219 Logger.metrics($params);
220 Logger.metrics($event);
221 Logger.metrics($manager);
222 Logger.metrics($clTimer);
224 // Check which event this is.
226 ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
227 Logger.info("Event status is " + eventStatus);
229 // Check what kind of event this is
231 if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
233 // We don't care about subsequent onsets
235 Logger.info("Retracting Subsequent Onset " + $event);
239 if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
241 // Ignore any bad syntax events
243 Logger.info("Retracting Bad Syntax Event " + $event);
248 // We only want the initial ONSET event in memory,
249 // all the other events need to be retracted to support
250 // cleanup and avoid the other rules being fired for this event.
252 if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
253 Logger.info("Retracting Event " + $event);
256 Logger.info("Checking due to new event " + $event.triggerID);
258 // Now start seeing if we need to process this event
262 // Check if this is a Final Event
264 ATTControlLoopNotification notification = $manager.isControlLoopFinal();
267 if (notification != null) {
269 // Its final, but are we waiting for abatement?
271 if ($manager.getNumAbatements() > 0) {
272 Logger.info("Abatement received, close out the control loop for " + $event.requestID);
273 notification.from = "policy";
274 notification.policyName = drools.getRule().getName();
275 notification.policyScope = "${policyScope}";
276 notification.policyVersion = "${policyVersion}";
278 // In this case, we are done
280 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
284 TargetLock lock = $manager.unlockCurrentOperation();
286 System.out.println("retracting lock " + lock);
290 // Retract everything from memory
292 System.out.println("retracting onset");
293 retract($manager.getOnsetEvent());
297 // TODO - what if we get subsequent Events for this RequestID?
298 // By default, it will all start over again. May be confusing for Ruby.
299 // Or, we could track this and then subsequently ignore the events
303 // Check whether we need to wait for abatement
305 if ($manager.getProcessor().getControlLoop().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
306 Logger.info("Waiting for abatement.");
308 Logger.info("No abatement is promised to come, close out the control loop for " + $event.requestID);
309 notification.from = "policy";
310 notification.policyName = drools.getRule().getName();
311 notification.policyScope = "${policyScope}";
312 notification.policyVersion = "${policyVersion}";
314 // In this case, we are done
316 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
320 TargetLock lock = $manager.unlockCurrentOperation();
322 System.out.println("retracting lock " + lock);
326 // Retract everything from memory
328 System.out.println("retracting onset");
329 retract($manager.getOnsetEvent());
336 // NOT final, so let's ask for the next operation
338 ControlLoopOperationManager operation = $manager.processControlLoop();
339 if (operation != null) {
340 Logger.info("starting a new operation" + operation);
342 // insert into memory
346 // insert operation timeout object
348 OperationTimer opTimer = new OperationTimer();
349 opTimer.setClosedLoopControlName($event.closedLoopControlName);
350 opTimer.setRequestID($event.requestID.toString());
351 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
355 // Let's ask for a lock right away
357 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
358 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
359 Logger.info("manager returned lock " + result.getB());
361 // Insert into memory
363 insert(result.getB());
367 // Probably waiting for abatement
371 } catch (Exception e) {
374 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
375 notification.notification = ControlLoopNotificationType.REJECTED;
376 notification.from = "policy";
377 notification.message = "Exception occurred " + e.getMessage();
378 notification.policyName = drools.getRule().getName();
379 notification.policyScope = "${policyScope}";
380 notification.policyVersion = "${policyVersion}";
384 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
386 // TODO should we abort if we get an exception?
398 rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
401 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
402 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
403 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
404 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
405 not ( TargetLock (requestID == $event.requestID) )
410 Logger.info("------------------------------------------------------------------------------------------------");
411 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
412 Logger.metrics($params);
413 Logger.metrics($manager);
414 Logger.metrics($operation);
416 // Need to ask for a Lock
418 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
419 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
420 Logger.info("Lock acquired: " + result.getB());
422 // Insert into memory
424 insert(result.getB());
433 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
435 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
436 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
437 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
438 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "Permit" )
439 $lock : TargetLock (requestID == $event.requestID)
444 Logger.info("------------------------------------------------------------------------------------------------");
445 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
446 Logger.metrics($params);
447 Logger.metrics($manager);
448 Logger.metrics($operation);
449 Logger.metrics($lock);
451 // Start the Operation
453 //Object request = $operation.startOperation($event);
454 //$operation.startOperation($event);
455 Object request = $operation.getOperationRequest();
457 if (request != null) {
458 Logger.info("Starting operation");
460 // Tell interested parties we are performing this Operation
462 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
463 notification.notification = ControlLoopNotificationType.OPERATION;
464 notification.message = $operation.getOperationMessage();
465 notification.history = $operation.getHistory();
466 notification.from = "policy";
467 notification.policyName = drools.getRule().getName();
468 notification.policyScope = "${policyScope}";
469 notification.policyVersion = "${policyVersion}";
470 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
472 // Send the APPC request
474 if (request instanceof Request) {
475 Engine.deliver("UEB", "APPC-CL", request);
478 // TODO: send different types of requests
483 // What happens if its null?
494 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
496 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
497 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
498 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
499 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "NONE" )
500 $lock : TargetLock (requestID == $event.requestID)
505 Logger.info("------------------------------------------------------------------------------------------------");
506 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
507 Logger.metrics($params);
508 Logger.metrics($manager);
509 Logger.metrics($operation);
510 Logger.metrics($lock);
512 $operation.startOperation($event);
514 // Now send Guard Request to XACML Guard
516 PolicyGuardXacmlRequestAttributes xacmlReq = new PolicyGuardXacmlRequestAttributes($operation.policy.actor.toString(), $operation.policy.recipe, $event.target, $event.requestID.toString());
517 //Engine.deliver("UEB", "GUARD-CL", xacmlReq/*request*/);
518 System.out.println("\n********** XACML REQUEST START ********");
519 System.out.println(RequestParser.parseRequest(xacmlReq));
520 System.out.println("********** XACML REQUEST END ********\n");
522 com.att.research.xacml.api.Response xacmlResponse = PolicyGuardXacmlHelper.callPDP(XacmlPdpEngine, "", (com.att.research.xacml.api.Request) RequestParser.parseRequest(xacmlReq), false);
524 System.out.println("\n********** XACML RESPONSE 1 START ********");
525 System.out.println(xacmlResponse);
526 System.out.println("********** XACML RESPONSE 1 END ********\n");
528 PolicyGuardResponse guardResponse = PolicyGuardXacmlHelper.ParseXacmlPdpResponse(xacmlResponse);
529 System.out.println("\n\n============ Guard inserted with decision "+ guardResponse.result + " !!! ===========\n\n");
532 insert(guardResponse);
538 rule "${policyName}.GUARD.RESPONSE"
540 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
541 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
542 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
543 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
544 $lock : TargetLock (requestID == $event.requestID)
545 $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
546 $guardResponse : PolicyGuardResponse(/*requestID == $event.requestID, $operation.policy.recipe == operation*/)
551 Logger.info("------------------------------------------------------------------------------------------------");
552 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
553 Logger.metrics($params);
554 Logger.metrics($event);
555 Logger.metrics($operation);
556 Logger.metrics($lock);
557 Logger.metrics($guardResponse);
560 //we will permit the operation if there was no Guard for it
561 if($guardResponse.result == "Indeterminate"){
562 $guardResponse.result = "Permit";
565 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
566 notification.notification = ControlLoopNotificationType.OPERATION;
567 notification.message = $operation.getOperationMessage($guardResponse.result);//"Guard result: " + $guardResponse.result;
568 notification.history = $operation.getHistory();
569 notification.from = "policy";
570 notification.policyName = drools.getRule().getName();
571 notification.policyScope = "${policyScope}";
572 notification.policyVersion = "${policyVersion}";
573 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
577 if($guardResponse.result == "Permit"){
579 modify($operation){setGuardApprovalStatus($guardResponse.result)};
582 //This is the Deny case
583 $operation.setOperationHasGuardDeny();
586 modify($manager) {finishOperation($operation)};
589 retract($guardResponse);
598 * This rule responds to APPC Response Events
600 * I would have like to be consistent and write the Response like this:
601 * $response : Response( CommonHeader.RequestID == $onset.requestID )
603 * However, no compile error was given. But a runtime error was given. I think
604 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
607 rule "${policyName}.APPC.RESPONSE"
609 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
610 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
611 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
612 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
613 $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
614 $lock : TargetLock (requestID == $event.requestID)
615 $response : Response( getCommonHeader().RequestID == $event.requestID )
620 Logger.info("------------------------------------------------------------------------------------------------");
621 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
622 Logger.metrics($params);
623 Logger.metrics($event);
624 Logger.metrics($manager);
625 Logger.metrics($operation);
626 Logger.metrics($opTimer);
627 Logger.metrics($lock);
628 Logger.metrics($response);
630 // Get the result of the operation
632 PolicyResult policyResult = $operation.onResponse($response);
633 if (policyResult != null) {
634 Logger.info("operation finished with result: " + policyResult);
636 // This Operation has completed, construct a notification showing our results
638 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
639 notification.from = "policy";
640 notification.policyName = drools.getRule().getName();
641 notification.policyScope = "${policyScope}";
642 notification.policyVersion = "${policyVersion}";
643 notification.message = $operation.getOperationHistory();
644 notification.history = $operation.getHistory();
645 if (policyResult.equals(PolicyResult.SUCCESS)) {
646 notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
648 // Let interested parties know
650 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
652 notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
654 // Let interested parties know
656 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
659 // Ensure the operation is complete
661 if ($operation.isOperationComplete() == true) {
663 // It is complete, remove it from memory
667 // We must also retract the timer object
668 // NOTE: We could write a Rule to do this
672 // Complete the operation
674 modify($manager) {finishOperation($operation)};
677 // Just doing this will kick off the LOCKED rule again
679 modify($operation) {};
683 // Its not finished yet (i.e. expecting more Response objects)
685 // Or possibly it is a leftover response that we timed the request out previously
689 // We are going to retract these objects from memory
696 * The problem with Responses is that they don't have a controlLoopControlName
697 * field in them, so the only way to attach them is via RequestID. If we have multiple
698 * control loop .drl's loaded in the same container, we need to be sure the cleanup
699 * rules don't remove Responses for other control loops.
702 rule "${policyName}.APPC.RESPONSE.CLEANUP"
704 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
705 $response : Response($id : getCommonHeader().RequestID )
706 not ( ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
711 Logger.info("------------------------------------------------------------------------------------------------");
712 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
713 Logger.metrics($params);
721 * This is the timer that manages the timeout for an individual operation.
724 rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT"
727 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
728 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
729 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
730 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
731 $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
732 $lock : TargetLock (requestID == $event.requestID)
737 Logger.info("------------------------------------------------------------------------------------------------");
738 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
739 Logger.metrics($params);
740 Logger.metrics($manager);
741 Logger.metrics($operation);
742 Logger.metrics($opTimer);
743 Logger.metrics($lock);
745 // Tell it its timed out
747 $operation.setOperationHasTimedOut();
749 // Create a notification for it
751 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
752 notification.from = "policy";
753 notification.policyName = drools.getRule().getName();
754 notification.policyScope = "${policyScope}";
755 notification.policyVersion = "${policyVersion}";
756 notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
757 notification.message = $operation.getOperationHistory();
758 notification.history = $operation.getHistory();
760 // Let interested parties know
762 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
764 // Get rid of the timer
768 // Ensure the operation is complete
770 if ($operation.isOperationComplete() == true) {
772 // It is complete, remove it from memory
776 // Complete the operation
778 modify($manager) {finishOperation($operation)};
781 // Just doing this will kick off the LOCKED rule again
783 modify($operation) {};
789 * This is the timer that manages the overall control loop timeout.
792 rule "${policyName}.EVENT.MANAGER.TIMEOUT"
795 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
796 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
797 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
798 $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
799 $operations : LinkedList()
800 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID ) )
801 $opTimers : LinkedList()
802 from collect( OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() ) )
803 $locks : LinkedList()
804 from collect( TargetLock (requestID == $event.requestID) )
809 Logger.info("------------------------------------------------------------------------------------------------");
810 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
811 Logger.metrics($params);
812 Logger.metrics($manager);
813 Logger.metrics($clTimer);
814 if ($operations == null) {
815 Logger.info("no operations found");
817 Logger.info("found " + $operations.size() + " operations");
820 // Tell the Event Manager it has timed out
822 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
823 if (notification != null) {
824 notification.from = "policy";
825 notification.policyName = drools.getRule().getName();
826 notification.policyScope = "${policyScope}";
827 notification.policyVersion = "${policyVersion}";
829 // Let interested parties know
831 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
834 // Retract EVERYTHING
839 if ($operations != null && $operations.size() > 0) {
840 Iterator<ControlLoopOperationManager> iter = $operations.iterator();
841 while (iter.hasNext()) {
842 ControlLoopOperationManager manager = iter.next();
846 if ($opTimers != null && $opTimers.size() > 0) {
847 Iterator<OperationTimer> iter = $opTimers.iterator();
848 while (iter.hasNext()) {
849 OperationTimer opTimer = iter.next();
853 if ($locks != null && $locks.size() > 0) {
854 Iterator<TargetLock> iter = $locks.iterator();
855 while (iter.hasNext()) {
856 TargetLock lock = iter.next();
858 // Ensure we release the lock
860 PolicyGuard.unlockTarget(lock);