[POLICY-22] Reorganizing drools-apps
[policy/drools-applications.git] / controlloop / templates / template.demo / src / main / resources / old / ControlLoop_Template_1610_v1.1_xacml_guard.drl
1 /*
2  *                        AT&T - PROPRIETARY
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.
6  *
7  *          Copyright (c) 2016 AT&T Knowledge Ventures
8  *              Unpublished and Not for Publication
9  *                     All Rights Reserved
10  */
11 package com.att.ecomp.policy.controlloop;
12
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;
37
38 //
39 // REPLACE THESE WITH PRODUCTION VERSIONS
40 //
41 import com.att.ecomp.policy.controlloop.ControlLoopLogger;
42 import com.att.ecomp.policy.drools.PolicyEngine;
43
44 global ControlLoopLogger Logger;
45 global PolicyEngine Engine;
46 global PDPEngine XacmlPdpEngine;
47
48 import java.time.Instant;
49 import java.util.LinkedList;
50 import java.util.Iterator;
51
52 declare Params
53     closedLoopControlName : String
54         controlLoopYaml : String
55 end
56
57 declare OperationTimer
58         closedLoopControlName : String
59         requestID : String
60         delay : String
61 end
62
63 declare ControlLoopTimer
64         closedLoopControlName : String
65         requestID : String
66         delay : String
67 end
68
69
70 /*
71 *
72 * Called once and only once to insert the parameters into working memory for this Closed Loop policy.
73 *
74 */
75 rule "${policyName}.SETUP"
76         when
77         then
78         //
79         // Logging
80         //
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}");
86                 insert(params);
87                 Logger.metrics("Inserted " + params);
88         Logger.info("------------------------------------------------------------------------------------------------");
89 end
90
91 /*
92 *
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)
95 *
96 */
97 rule "${policyName}.EVENT"
98         when
99         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
100         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
101         not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
102         then
103                 try {
104                 //
105                 // Logging
106                 //
107                 Logger.info("------------------------------------------------------------------------------------------------");
108                 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
109                         //
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.
113                         //
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}";
122                                 //
123                                 // Let interested parties know
124                                 //
125                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
126                                 //
127                                 // Retract it from memory
128                                 //
129                                 retract($event);
130                         } else {
131                                 //
132                                 // Create an EventManager
133                                 //
134                                 ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
135                                 //
136                                 // Determine if EventManager can actively process the event (i.e. syntax, is_closed_loop_disabled checks etc.)
137                                 //
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}";
143                                 //
144                                 // Are we actively pursuing this event?
145                                 //
146                                 if (notification.notification == ControlLoopNotificationType.ACTIVE) {
147                                         //
148                                         // Insert Event Manager into memory, this will now kick off processing.
149                                         //
150                                         insert(manager);
151                                         //
152                                         // Let interested parties know
153                                         //
154                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
155                                         //
156                                         // Setup the Overall Control Loop timer
157                                         //
158                                         ControlLoopTimer clTimer = new ControlLoopTimer();
159                                         clTimer.setClosedLoopControlName($event.closedLoopControlName);
160                                         clTimer.setRequestID($event.requestID.toString());
161                                         clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
162                                         //
163                                         // Insert it
164                                         //
165                                         insert(clTimer);
166                                 } else {
167                                         //
168                                         // Let interested parties know
169                                         //
170                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
171                                         //
172                                         // Retract it from memory
173                                         //
174                                         retract($event);
175                                 }
176                                 //
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.
180                                 //
181                         }
182                 } catch (Exception e) {
183                         e.printStackTrace();
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}";
190                         //
191                         //
192                         //
193                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
194                         //
195                         // Retract the event
196                         //
197                         retract($event);
198                 }
199 end
200
201 /*
202 *
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.
205 *
206 */
207 rule "${policyName}.EVENT.MANAGER"
208     when
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() )
213         then
214         //
215         // Logging
216         //
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);
223                 //
224                 // Check which event this is.
225                 //
226                 ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
227                 Logger.info("Event status is " + eventStatus);
228                 //
229                 // Check what kind of event this is
230                 //
231                 if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
232                         //
233                         // We don't care about subsequent onsets
234                         //
235                         Logger.info("Retracting Subsequent Onset " + $event);
236                         retract($event);
237                         return;
238                 }
239                 if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
240                         //
241                         // Ignore any bad syntax events
242                         //
243                         Logger.info("Retracting Bad Syntax Event " + $event);
244                         retract($event);
245                         return;
246                 }
247                 //
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.
251                 //
252                 if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
253                         Logger.info("Retracting Event " + $event);
254                         retract($event);
255                 }
256                 Logger.info("Checking due to new event " + $event.triggerID);
257                 //
258                 // Now start seeing if we need to process this event
259                 //
260                 try {
261                         //
262                         // Check if this is a Final Event
263                         //
264                         ATTControlLoopNotification notification = $manager.isControlLoopFinal();
265                 
266                 
267                         if (notification != null) {
268                                 //
269                                 // Its final, but are we waiting for abatement?
270                                 //
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}";
277                                         //
278                                         // In this case, we are done
279                                         //
280                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
281                                         //
282                                         // Unlock the target
283                                         //
284                                         TargetLock lock = $manager.unlockCurrentOperation();
285                                         if (lock != null) {
286                                                 System.out.println("retracting lock " + lock);
287                                                 retract(lock);
288                                         }
289                                         //
290                                         // Retract everything from memory
291                                         //
292                                         System.out.println("retracting onset");
293                                         retract($manager.getOnsetEvent());
294                                         retract($manager);
295                                         retract($clTimer);
296                                         //
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
300                                         //
301                                 } else {
302                                         //
303                                         // Check whether we need to wait for abatement
304                                         //
305                                         if ($manager.getProcessor().getControlLoop().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
306                                                 Logger.info("Waiting for abatement.");
307                                         } else {
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}";
313                                                 //
314                                                 // In this case, we are done
315                                                 //
316                                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
317                                                 //
318                                                 // Unlock the target
319                                                 //
320                                                 TargetLock lock = $manager.unlockCurrentOperation();
321                                                 if (lock != null) {
322                                                         System.out.println("retracting lock " + lock);
323                                                         retract(lock);
324                                                 }
325                                                 //
326                                                 // Retract everything from memory
327                                                 //
328                                                 System.out.println("retracting onset");
329                                                 retract($manager.getOnsetEvent());
330                                                 retract($manager);
331                                                 retract($clTimer);
332                                         }
333                                 }
334                         } else {
335                                 //
336                                 // NOT final, so let's ask for the next operation
337                                 //
338                                 ControlLoopOperationManager operation = $manager.processControlLoop();
339                                 if (operation != null) {
340                                         Logger.info("starting a new operation" + operation);
341                                         //
342                                         // insert into memory
343                                         //
344                                         insert(operation);
345                                         //
346                                         // insert operation timeout object
347                                         //
348                                         OperationTimer opTimer = new OperationTimer();
349                                         opTimer.setClosedLoopControlName($event.closedLoopControlName);
350                                         opTimer.setRequestID($event.requestID.toString());
351                                         opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
352                                         insert(opTimer);
353                         
354                                         //
355                                         // Let's ask for a lock right away
356                                         //
357                                         LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
358                                         if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
359                                                 Logger.info("manager returned lock " + result.getB());
360                                                 //
361                                                 // Insert into memory
362                                                 //
363                                                 insert(result.getB());
364                                         }
365                                 } else {
366                                         //
367                                         // Probably waiting for abatement
368                                         //
369                                 }
370                         }
371                 } catch (Exception e) {
372                         e.printStackTrace();
373                         /*
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}";
381                         //
382                         //
383                         //
384                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
385                         //
386                         // TODO should we abort if we get an exception?
387                         //
388                         */
389                 }
390                 
391 end
392
393 /*
394 *
395
396 *
397 */
398 rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
399         timer (int: 5s 5s)
400     when
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) )
406         then
407         //
408         // Logging
409         //
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);
415                 //
416                 // Need to ask for a Lock
417                 //
418                 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
419                 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
420                         Logger.info("Lock acquired: " + result.getB());
421                         //
422                         // Insert into memory
423                         //
424                         insert(result.getB());
425                 }
426 end
427
428 /*
429 *
430
431 *
432 */
433 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
434     when
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)
440         then
441         //
442         // Logging
443         //
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);
450                 //
451                 // Start the Operation
452                 //
453                 //Object request = $operation.startOperation($event);
454                 //$operation.startOperation($event);
455                 Object request = $operation.getOperationRequest();
456                 
457                 if (request != null) {
458                         Logger.info("Starting operation");
459                         //
460                         // Tell interested parties we are performing this Operation
461                         //
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);
471                         //
472                         // Send the APPC request
473                         //
474                         if (request instanceof Request) {
475                                 Engine.deliver("UEB", "APPC-CL", request);
476                         }
477                         //
478                         // TODO: send different types of requests
479                         //
480                         
481                 } else {
482                         //
483                         // What happens if its null?
484                         //
485                 }
486 end
487
488
489 /*
490 *
491
492 *
493 */
494 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
495     when
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)
501         then
502         //
503         // Logging
504         //
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);
511
512                 $operation.startOperation($event);
513                 //
514                 // Now send Guard Request to XACML Guard
515                 //
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");
521                 
522             com.att.research.xacml.api.Response xacmlResponse = PolicyGuardXacmlHelper.callPDP(XacmlPdpEngine, "", (com.att.research.xacml.api.Request) RequestParser.parseRequest(xacmlReq), false);
523             
524             System.out.println("\n********** XACML RESPONSE 1 START ********");
525                 System.out.println(xacmlResponse);
526                 System.out.println("********** XACML RESPONSE 1 END ********\n");
527                                         
528             PolicyGuardResponse guardResponse = PolicyGuardXacmlHelper.ParseXacmlPdpResponse(xacmlResponse);
529             System.out.println("\n\n============ Guard inserted with decision "+ guardResponse.result + " !!! ===========\n\n");
530             
531             
532             insert(guardResponse);
533
534 end
535
536
537
538 rule "${policyName}.GUARD.RESPONSE"
539     when
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*/)
547         then
548         //
549         // Logging
550         //
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);
558                 
559                 
560                 //we will permit the operation if there was no Guard for it
561                 if($guardResponse.result == "Indeterminate"){
562                         $guardResponse.result = "Permit";
563                 }
564                 
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);
574                 
575                 
576                 
577                 if($guardResponse.result == "Permit"){
578                 
579                         modify($operation){setGuardApprovalStatus($guardResponse.result)};
580                 }
581                 else {
582                         //This is the Deny case
583                         $operation.setOperationHasGuardDeny();
584                         retract($opTimer);
585                         retract($operation);
586                         modify($manager) {finishOperation($operation)};
587                 }
588                 
589                 retract($guardResponse);
590                         
591 end
592
593
594
595
596 /*
597 *
598 * This rule responds to APPC Response Events
599 *
600 * I would have like to be consistent and write the Response like this:
601 * $response : Response( CommonHeader.RequestID == $onset.requestID )
602 *
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.
605 *
606 */
607 rule "${policyName}.APPC.RESPONSE"
608     when
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 )
616         then
617         //
618         // Logging
619         //
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);
629                 //
630                 // Get the result of the operation
631                 //
632                 PolicyResult policyResult = $operation.onResponse($response);
633                 if (policyResult != null) {
634                         Logger.info("operation finished with result: " + policyResult);
635                         //
636                         // This Operation has completed, construct a notification showing our results
637                         //
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;
647                                 //
648                                 // Let interested parties know
649                                 //
650                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
651                         } else {
652                                 notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
653                                 //
654                                 // Let interested parties know
655                                 //
656                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
657                         }
658                         //
659                         // Ensure the operation is complete
660                         //
661                         if ($operation.isOperationComplete() == true) {
662                                 //
663                                 // It is complete, remove it from memory
664                                 //
665                                 retract($operation);
666                                 //
667                                 // We must also retract the timer object
668                                 // NOTE: We could write a Rule to do this
669                                 //
670                                 retract($opTimer);
671                                 //
672                                 // Complete the operation
673                                 //
674                                 modify($manager) {finishOperation($operation)};
675                         } else {
676                                 //
677                                 // Just doing this will kick off the LOCKED rule again
678                                 //
679                                 modify($operation) {};
680                         }
681                 } else {
682                         //
683                         // Its not finished yet (i.e. expecting more Response objects)
684                         //
685                         // Or possibly it is a leftover response that we timed the request out previously
686                         //
687                 }
688                 //
689                 // We are going to retract these objects from memory
690                 //
691                 retract($response);
692 end
693
694 /*
695 *
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.
700 *
701 */
702 rule "${policyName}.APPC.RESPONSE.CLEANUP"
703     when
704         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
705         $response : Response($id : getCommonHeader().RequestID )
706                 not ( ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) 
707         then
708         //
709         // Logging
710         //
711         Logger.info("------------------------------------------------------------------------------------------------");
712         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
713                 Logger.metrics($params);
714                 //
715                 // Retract it
716                 //
717                 retract($response);
718 end
719 /*
720 *
721 * This is the timer that manages the timeout for an individual operation.
722 *
723 */
724 rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT"
725         timer (expr: $to )
726     when
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)
733         then
734         //
735         // Logging
736         //
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);
744                 //
745                 // Tell it its timed out
746                 //
747                 $operation.setOperationHasTimedOut();
748                 //
749                 // Create a notification for it
750                 //
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();
759                 //
760                 // Let interested parties know
761                 //
762                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
763                 //
764                 // Get rid of the timer
765                 //
766                 retract($opTimer);
767                 //
768                 // Ensure the operation is complete
769                 //
770                 if ($operation.isOperationComplete() == true) {
771                         //
772                         // It is complete, remove it from memory
773                         //
774                         retract($operation);
775                         //
776                         // Complete the operation
777                         //
778                         modify($manager) {finishOperation($operation)};
779                 } else {
780                         //
781                         // Just doing this will kick off the LOCKED rule again
782                         //
783                         modify($operation) {};
784                 }
785 end
786
787 /*
788 *
789 * This is the timer that manages the overall control loop timeout.
790 *
791 */
792 rule "${policyName}.EVENT.MANAGER.TIMEOUT"
793         timer (expr: $to )
794     when
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) )
805         then
806         //
807         // Logging
808         //
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");
816                 } else {
817                         Logger.info("found " + $operations.size() + " operations");
818                 }
819                 //
820                 // Tell the Event Manager it has timed out
821                 //
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}";
828                         //
829                         // Let interested parties know
830                         //
831                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
832                 }
833                 //
834                 // Retract EVERYTHING
835                 //
836                 retract($event);
837                 retract($manager);
838                 retract($clTimer);
839                 if ($operations != null && $operations.size() > 0) {
840                         Iterator<ControlLoopOperationManager> iter = $operations.iterator();
841                         while (iter.hasNext()) {
842                                 ControlLoopOperationManager manager = iter.next();
843                                 retract(manager);
844                         }
845                 }
846                 if ($opTimers != null && $opTimers.size() > 0) {
847                         Iterator<OperationTimer> iter = $opTimers.iterator();
848                         while (iter.hasNext()) {
849                                 OperationTimer opTimer = iter.next();
850                                 retract(opTimer);
851                         }
852                 }
853                 if ($locks != null && $locks.size() > 0) {
854                         Iterator<TargetLock> iter = $locks.iterator();
855                         while (iter.hasNext()) {
856                                 TargetLock lock = iter.next();
857                                 //
858                                 // Ensure we release the lock
859                                 //
860                                 PolicyGuard.unlockTarget(lock);
861                                 //
862                                 //
863                                 //
864                                 retract(lock);
865                         }
866                 }
867 end