[POLICY-22] Reorganizing drools-apps
[policy/drools-applications.git] / controlloop / templates / template.demo / src / main / resources / old / ControlLoop_Template_1707_xacml_guard_enodeb.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 import com.att.ecomp.policy.controlloop.policy.ControlLoopPolicy;
38 import com.att.ecomp.policy.controlloop.policy.Policy;
39 import java.net.URLDecoder;
40 import org.eclipse.persistence.exceptions.DatabaseException;
41
42 //
43 // REPLACE THESE WITH PRODUCTION VERSIONS
44 //
45 import com.att.ecomp.policy.controlloop.ControlLoopLogger;
46 import com.att.ecomp.policy.drools.PolicyEngine;
47 import org.yaml.snakeyaml.Yaml;
48 import org.yaml.snakeyaml.constructor.Constructor;
49
50 global ControlLoopLogger Logger;
51 global PolicyEngine Engine;
52 global PDPEngine XacmlPdpEngine;
53
54 import java.time.Instant;
55 import java.util.LinkedList;
56 import java.util.Iterator;
57
58 declare Params
59     closedLoopControlName : String
60         controlLoopYaml : String
61 end
62
63 declare EnbParams
64     enbOperationsPeriodicTimer : String
65 end
66
67
68 declare OperationTimer
69         closedLoopControlName : String
70         requestID : String
71         delay : String
72 end
73
74 declare ControlLoopTimer
75         closedLoopControlName : String
76         requestID : String
77         delay : String
78 end
79
80
81 /*
82 *
83 * Called once and only once to insert the parameters into working memory for this Closed Loop policy.
84 *
85 */
86 rule "${policyName}.SETUP"
87         when
88         then
89         //
90         // Logging
91         //
92         Logger.info("------------------------------------------------------------------------------------------------");
93         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
94                 Params params = new Params();
95                 params.setClosedLoopControlName("${closedLoopControlName}");
96                 params.setControlLoopYaml("${controlLoopYaml}");
97                 insert(params);
98                 Logger.metrics("Inserted " + params);
99         Logger.info("------------------------------------------------------------------------------------------------");
100         EnbParams enbParams = new EnbParams();
101         
102         //
103         //Fetching the eNodeB timer from the Yaml
104         //
105         Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
106                 Object obj = yaml.load(URLDecoder.decode(params.getControlLoopYaml(), "UTF-8"));
107                 
108                 enbParams.setEnbOperationsPeriodicTimer("0s");
109                 for(Policy policy : ((ControlLoopPolicy)obj).policies){
110                         if(policy.actor.equals("APPC")){
111                                 if(policy.payload != null){
112                                         if(policy.payload.containsKey("enbOperationPeriodicTimer")){
113                                                 enbParams.setEnbOperationsPeriodicTimer(policy.payload.get("enbOperationPeriodicTimer"));
114                                         }
115                                 }
116                                 break;
117                         }
118                 }       
119         insert(enbParams);
120         System.out.println("################ got timer: " + enbParams.getEnbOperationsPeriodicTimer());
121
122 end
123
124 /*
125 *
126 * This rule responds to DCAE Events where there is no manager yet. Either it is
127 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
128 *
129 */
130 rule "${policyName}.EVENT"
131         when
132         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
133         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
134         not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
135         then
136                 try {
137                 //
138                 // Logging
139                 //
140                 Logger.info("------------------------------------------------------------------------------------------------");
141                 Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
142                         //
143                         // Check the event, because we need it to not be null when
144                         // we create the ControlLoopEventManager. The ControlLoopEventManager
145                         // will do extra syntax checking as well check if the closed loop is disabled.
146                         //
147                         if ($event.requestID == null) {
148                                 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
149                                 notification.notification = ControlLoopNotificationType.REJECTED;
150                                 notification.from = "policy";
151                                 notification.message = "Missing requestID";
152                                 notification.policyName = drools.getRule().getName();
153                                 notification.policyScope = "${policyScope}";
154                                 notification.policyVersion = "${policyVersion}";
155                                 //
156                                 // Let interested parties know
157                                 //
158                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
159                                 //
160                                 // Retract it from memory
161                                 //
162                                 retract($event);
163                         } else {
164                                 //
165                                 // Create an EventManager
166                                 //
167                                 ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
168                                 //
169                                 // Determine if EventManager can actively process the event (i.e. syntax, is_closed_loop_disabled checks etc.)
170                                 //
171                                 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
172                                 notification.from = "pdp-0001-controller=controlloop"; // Engine.getInstanceName()
173                                 notification.policyName = drools.getRule().getName();
174                                 notification.policyScope = "${policyScope}";
175                                 notification.policyVersion = "${policyVersion}";
176                                 //
177                                 // Are we actively pursuing this event?
178                                 //
179                                 if (notification.notification == ControlLoopNotificationType.ACTIVE) {
180                                         //
181                                         // Insert Event Manager into memory, this will now kick off processing.
182                                         //
183                                         insert(manager);
184                                         //
185                                         // Let interested parties know
186                                         //
187                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
188                                         //
189                                         // Setup the Overall Control Loop timer
190                                         //
191                                         ControlLoopTimer clTimer = new ControlLoopTimer();
192                                         clTimer.setClosedLoopControlName($event.closedLoopControlName);
193                                         clTimer.setRequestID($event.requestID.toString());
194                                         clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
195                                         //
196                                         // Insert it
197                                         //
198                                         insert(clTimer);
199                                 } else {
200                                         //
201                                         // Let interested parties know
202                                         //
203                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
204                                         //
205                                         // Retract it from memory
206                                         //
207                                         retract($event);
208                                 }
209                                 //
210                                 // Now that the manager is inserted into Drools working memory, we'll wait for
211                                 // another rule to fire in order to continue processing. This way we can also
212                                 // then screen for additional ONSET and ABATED events for this RequestID.
213                                 //
214                         }
215                 } catch (Exception e) {
216                         e.printStackTrace();
217                         ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
218                         notification.notification = ControlLoopNotificationType.REJECTED;
219                         notification.message = "Exception occurred " + e.getMessage();
220                         notification.policyName = drools.getRule().getName();
221                         notification.policyScope = "${policyScope}";
222                         notification.policyVersion = "${policyVersion}";
223                         //
224                         //
225                         //
226                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
227                         //
228                         // Retract the event
229                         //
230                         retract($event);
231                 }
232 end
233
234 /*
235 *
236 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
237 * is now created. We can start processing the yaml specification via the Event Manager.
238 *
239 */
240 rule "${policyName}.EVENT.MANAGER"
241     when
242         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
243         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
244         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
245         $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
246         then
247         //
248         // Logging
249         //
250         Logger.info("------------------------------------------------------------------------------------------------");
251         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
252                 Logger.metrics($params);
253                 Logger.metrics($event);
254                 Logger.metrics($manager);
255                 Logger.metrics($clTimer);
256                 //
257                 // Check which event this is.
258                 //
259                 ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
260                 Logger.info("Event status is " + eventStatus);
261                 //
262                 // Check what kind of event this is
263                 //
264                 if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
265                         //
266                         // We don't care about subsequent onsets
267                         //
268                         Logger.info("Retracting Subsequent Onset " + $event);
269                         retract($event);
270                         return;
271                 }
272                 if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
273                         //
274                         // Ignore any bad syntax events
275                         //
276                         Logger.info("Retracting Bad Syntax Event " + $event);
277                         retract($event);
278                         return;
279                 }
280                 //
281                 // We only want the initial ONSET event in memory,
282                 // all the other events need to be retracted to support
283                 // cleanup and avoid the other rules being fired for this event.
284                 //
285                 if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
286                         Logger.info("Retracting Event " + $event);
287                         retract($event);
288                 }
289                 Logger.info("Checking due to new event " + $event.triggerID);
290                 //
291                 // Now start seeing if we need to process this event
292                 //
293                 try {
294                         //
295                         // Check if this is a Final Event
296                         //
297                         ATTControlLoopNotification notification = $manager.isControlLoopFinal();
298                 
299                 
300                         if (notification != null) {
301                                 //
302                                 // Its final, but are we waiting for abatement?
303                                 //
304                                 if ($manager.getNumAbatements() > 0) {
305                                         Logger.info("Abatement received, close out the control loop for " + $event.requestID);
306                                         notification.from = "policy";
307                                         notification.policyName = drools.getRule().getName();
308                                         notification.policyScope = "${policyScope}";
309                                         notification.policyVersion = "${policyVersion}";
310                                         //
311                                         // In this case, we are done
312                                         //
313                                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
314                                         //
315                                         // Unlock the target
316                                         //
317                                         TargetLock lock = $manager.unlockCurrentOperation();
318                                         if (lock != null) {
319                                                 System.out.println("retracting lock " + lock);
320                                                 retract(lock);
321                                         }
322                                         //
323                                         // Retract everything from memory
324                                         //
325                                         System.out.println("retracting onset");
326                                         retract($manager.getOnsetEvent());
327                                         retract($manager);
328                                         retract($clTimer);
329                                         //
330                                         // TODO - what if we get subsequent Events for this RequestID?
331                                         // By default, it will all start over again. May be confusing for Ruby.
332                                         // Or, we could track this and then subsequently ignore the events
333                                         //
334                                 } else {
335                                         //
336                                         // Check whether we need to wait for abatement
337                                         //
338                                         if ($manager.getProcessor().getControlLoop().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
339                                                 Logger.info("Waiting for abatement.");
340                                         } else {
341                                                 Logger.info("No abatement is promised to come, close out the control loop for " + $event.requestID);
342                                                 notification.from = "policy";
343                                                 notification.policyName = drools.getRule().getName();
344                                                 notification.policyScope = "${policyScope}";
345                                                 notification.policyVersion = "${policyVersion}";
346                                                 //
347                                                 // In this case, we are done
348                                                 //
349                                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
350                                                 //
351                                                 // Unlock the target
352                                                 //
353                                                 TargetLock lock = $manager.unlockCurrentOperation();
354                                                 if (lock != null) {
355                                                         System.out.println("retracting lock " + lock);
356                                                         retract(lock);
357                                                 }
358                                                 //
359                                                 // Retract everything from memory
360                                                 //
361                                                 System.out.println("retracting onset");
362                                                 retract($manager.getOnsetEvent());
363                                                 retract($manager);
364                                                 retract($clTimer);
365                                         }
366                                 }
367                         } else {
368                                 //
369                                 // NOT final, so let's ask for the next operation
370                                 //
371                                 ControlLoopOperationManager operation = $manager.processControlLoop();
372                                 if (operation != null) {
373                                         Logger.info("starting a new operation" + operation);
374                                         //
375                                         // insert into memory
376                                         //
377                                         insert(operation);
378                                         //
379                                         // insert operation timeout object
380                                         //
381                                         OperationTimer opTimer = new OperationTimer();
382                                         opTimer.setClosedLoopControlName($event.closedLoopControlName);
383                                         opTimer.setRequestID($event.requestID.toString());
384                                         opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
385                                         insert(opTimer);
386                         
387                                         //
388                                         // Let's ask for a lock right away
389                                         //
390                                         LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
391                                         if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
392                                                 Logger.info("manager returned lock " + result.getB());
393                                                 //
394                                                 // Insert into memory
395                                                 //
396                                                 insert(result.getB());
397                                         }
398                                 } else {
399                                         //
400                                         // Probably waiting for abatement
401                                         //
402                                 }
403                         }
404                 } catch (Exception e) {
405                         e.printStackTrace();
406                         /*
407                         ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
408                         notification.notification = ControlLoopNotificationType.REJECTED;
409                         notification.from = "policy";
410                         notification.message = "Exception occurred " + e.getMessage();
411                         notification.policyName = drools.getRule().getName();
412                         notification.policyScope = "${policyScope}";
413                         notification.policyVersion = "${policyVersion}";
414                         //
415                         //
416                         //
417                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
418                         //
419                         // TODO should we abort if we get an exception?
420                         //
421                         */
422                 }
423                 
424 end
425
426 /*
427 *
428
429 *
430 */
431 rule "${policyName}.PERIODIC_CHECK_OF_PENDING_ENB_OPERATIONS"
432         timer (expr: "0s", $t)
433         when
434                 $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
435                 $enbParams : EnbParams($t : getEnbOperationsPeriodicTimer())
436                 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
437                 $operations : LinkedList(size() > 0)
438                                         from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName) )
439        
440         then
441                 System.out.println(drools.getRule().getName() + " ********** operations size: " + $operations.size());
442                 //System.out.println(drools.getRule().getName());
443                 //The limt of 5 should also be defined in Yaml.
444 end
445
446
447 /*
448 *
449
450 *
451 */
452 rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
453         timer (int: 5s 5s)
454     when
455         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
456         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
457         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
458         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
459         not ( TargetLock (requestID == $event.requestID) )
460         then
461         //
462         // Logging
463         //
464         Logger.info("------------------------------------------------------------------------------------------------");
465         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
466                 Logger.metrics($params);
467                 Logger.metrics($manager);
468                 Logger.metrics($operation);
469                 //
470                 // Need to ask for a Lock
471                 //
472                 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
473                 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
474                         Logger.info("Lock acquired: " + result.getB());
475                         //
476                         // Insert into memory
477                         //
478                         insert(result.getB());
479                 }
480 end
481
482 /*
483 *
484 * Guard Permitted, let's send request to the actor.
485 *
486 */
487 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
488     when
489         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
490         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
491         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
492         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "Permit" )
493         $lock : TargetLock (requestID == $event.requestID)
494         then
495         //
496         // Logging
497         //
498         Logger.info("------------------------------------------------------------------------------------------------");
499         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
500                 Logger.metrics($params);
501                 Logger.metrics($manager);
502                 Logger.metrics($operation);
503                 Logger.metrics($lock);
504                 
505
506                 Object request = $operation.getOperationRequest();
507                 
508                 if (request != null) {
509                         Logger.info("Starting operation");
510                         //
511                         // Tell interested parties we are performing this Operation
512                         //
513                         ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
514                         notification.notification = ControlLoopNotificationType.OPERATION;
515                         notification.message = $operation.getOperationMessage();
516                         notification.history = $operation.getHistory();
517                         notification.from = "policy";
518                         notification.policyName = drools.getRule().getName();
519                         notification.policyScope = "${policyScope}";
520                         notification.policyVersion = "${policyVersion}";
521                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
522                         
523                         switch ($operation.policy.actor){
524                                 
525                                 case "APPC":
526                         
527                                         if (request instanceof Request) {
528                                                 Engine.deliver("UEB", "APPC-CL", request);
529                                         }
530                                 case "SDNR":
531                                 default:
532                         }
533                         
534                         
535                 } else {
536                         //
537                         // What happens if its null?
538                         //
539                 }
540 end
541
542
543 /*
544 *
545 * We were able to acquire a lock so now let's ask Xacml Guard whether we are allowed to proceed with the request to the actor.
546 *
547 */
548 rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
549     when
550         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
551         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
552         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
553         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "NONE" )
554         $lock : TargetLock (requestID == $event.requestID)
555         then
556         //
557         // Logging
558         //
559         Logger.info("------------------------------------------------------------------------------------------------");
560         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
561                 Logger.metrics($params);
562                 Logger.metrics($manager);
563                 Logger.metrics($operation);
564                 Logger.metrics($lock);
565
566
567                 
568                 
569                 //
570                 // We are starting the operation but the actor won't be contacted until Guard is queried and permitted.
571                 //
572                 $operation.startOperation($event);
573                 
574                 //
575                 // Sending notification that we are about to query Guard ("DB write - start operation")
576                 //
577                 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
578                 notification.notification = ControlLoopNotificationType.OPERATION;
579                 notification.message = $operation.getOperationMessage();
580                 notification.history = $operation.getHistory();
581                 notification.from = "policy";
582                 notification.policyName = drools.getRule().getName();
583                 notification.policyScope = "${policyScope}";
584                 notification.policyVersion = "${policyVersion}";
585                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
586                 
587                 //
588                 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard, just change guardEnabled to false.
589                 // 
590                 // In order to use REST XACML, provide a URL instead of "" as a second argument o the CallGuardTask() and set the first 
591                 // argument to null (instead of XacmlPdpEngine).
592                 //
593                 boolean guardEnabled = true;
594                 
595                 if(guardEnabled){
596                 
597                         Thread t = new Thread(new com.att.ecomp.policy.guard.CallGuardTask(
598                                                                                                                 XacmlPdpEngine, 
599                                                                                                                 "", 
600                                                                                                                 drools.getWorkingMemory(), 
601                                                                                                                 $operation.policy.actor.toString(),
602                                                                                                                 $operation.policy.recipe,
603                                                                                                                 $event.target,
604                                                                                                                 $event.requestID.toString()
605                                                                                                                 ));
606                     t.start();
607             }
608             else{
609                 insert(new PolicyGuardResponse("Permit", $event.requestID, $operation.policy.recipe));
610             }
611                 
612                 
613                 
614
615 end
616
617 //
618 //This rule will be triggered when a thread talking to the XACML Guard inserts a guardResponse object into the working memory
619 //
620 rule "${policyName}.GUARD.RESPONSE"
621     when
622         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
623                 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
624                 $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) 
625         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
626         $lock : TargetLock (requestID == $event.requestID)
627         $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
628         $guardResponse : PolicyGuardResponse(requestID == $event.requestID, $operation.policy.recipe == operation)
629         then
630         //
631         // Logging
632         //
633         Logger.info("------------------------------------------------------------------------------------------------");
634         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
635                 Logger.metrics($params);
636                 Logger.metrics($event);
637                 Logger.metrics($operation);
638                 Logger.metrics($lock);
639                 Logger.metrics($guardResponse);
640                 
641                 
642                 //we will permit the operation if there was no Guard for it
643                 if($guardResponse.result == "Indeterminate"){
644                         $guardResponse.result = "Permit";
645                 }
646                 
647                 //
648                 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
649                 //
650                 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
651                 notification.notification = ControlLoopNotificationType.OPERATION;
652                 notification.message = $operation.getOperationMessage($guardResponse.result);
653                 notification.history = $operation.getHistory();
654                 notification.from = "policy";
655                 notification.policyName = drools.getRule().getName();
656                 notification.policyScope = "${policyScope}";
657                 notification.policyVersion = "${policyVersion}";
658                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
659                 
660                 
661                 
662                 if($guardResponse.result == "Permit"){
663                 
664                         modify($operation){setGuardApprovalStatus($guardResponse.result)};
665                 }
666                 else {
667                         //This is the Deny case
668                         $operation.setOperationHasGuardDeny();
669                         retract($opTimer);
670                         retract($operation);
671                         modify($manager) {finishOperation($operation)};
672                 }
673                 
674                 retract($guardResponse);
675                         
676 end
677
678
679
680
681 /*
682 *
683 * This rule responds to APPC Response Events
684 *
685 * I would have like to be consistent and write the Response like this:
686 * $response : Response( CommonHeader.RequestID == $onset.requestID )
687 *
688 * However, no compile error was given. But a runtime error was given. I think
689 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
690 *
691 */
692 rule "${policyName}.APPC.RESPONSE"
693     when
694         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
695                 $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) 
696         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
697         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
698         $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
699         $lock : TargetLock (requestID == $event.requestID)
700         $response : Response( getCommonHeader().RequestID == $event.requestID )
701         then
702         //
703         // Logging
704         //
705         Logger.info("------------------------------------------------------------------------------------------------");
706         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
707                 Logger.metrics($params);
708                 Logger.metrics($event);
709                 Logger.metrics($manager);
710                 Logger.metrics($operation);
711                 Logger.metrics($opTimer);
712                 Logger.metrics($lock);
713                 Logger.metrics($response);
714                 //
715                 // Get the result of the operation
716                 //
717                 PolicyResult policyResult = $operation.onResponse($response);
718                 if (policyResult != null) {
719                         Logger.info("operation finished with result: " + policyResult);
720                         //
721                         // This Operation has completed, construct a notification showing our results. (DB write - end operation)
722                         //
723                         ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
724                         notification.from = "policy";
725                         notification.policyName = drools.getRule().getName();
726                         notification.policyScope = "${policyScope}";
727                         notification.policyVersion = "${policyVersion}";
728                         notification.message = $operation.getOperationHistory();
729                         notification.history = $operation.getHistory();
730                         if (policyResult.equals(PolicyResult.SUCCESS)) {
731                                 notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
732                                 //
733                                 // Let interested parties know
734                                 //
735                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
736                         } else {
737                                 notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
738                                 //
739                                 // Let interested parties know
740                                 //
741                                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
742                         }
743                         //
744                         // Ensure the operation is complete
745                         //
746                         if ($operation.isOperationComplete() == true) {
747                                 //
748                                 // It is complete, remove it from memory
749                                 //
750                                 retract($operation);
751                                 //
752                                 // We must also retract the timer object
753                                 // NOTE: We could write a Rule to do this
754                                 //
755                                 retract($opTimer);
756                                 //
757                                 // Complete the operation
758                                 //
759                                 modify($manager) {finishOperation($operation)};
760                         } else {
761                                 //
762                                 // Just doing this will kick off the LOCKED rule again
763                                 //
764                                 modify($operation) {};
765                         }
766                 } else {
767                         //
768                         // Its not finished yet (i.e. expecting more Response objects)
769                         //
770                         // Or possibly it is a leftover response that we timed the request out previously
771                         //
772                 }
773                 //
774                 // We are going to retract these objects from memory
775                 //
776                 retract($response);
777 end
778
779 /*
780 *
781 * The problem with Responses is that they don't have a controlLoopControlName
782 * field in them, so the only way to attach them is via RequestID. If we have multiple
783 * control loop .drl's loaded in the same container, we need to be sure the cleanup
784 * rules don't remove Responses for other control loops.
785 *
786 */
787 rule "${policyName}.APPC.RESPONSE.CLEANUP"
788     when
789         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
790         $response : Response($id : getCommonHeader().RequestID )
791                 not ( ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) 
792         then
793         //
794         // Logging
795         //
796         Logger.info("------------------------------------------------------------------------------------------------");
797         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
798                 Logger.metrics($params);
799                 //
800                 // Retract it
801                 //
802                 retract($response);
803 end
804 /*
805 *
806 * This is the timer that manages the timeout for an individual operation.
807 *
808 */
809 rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT"
810         timer (expr: $to )
811     when
812         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
813         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
814         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
815         $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
816         $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
817         $lock : TargetLock (requestID == $event.requestID)
818         then
819         //
820         // Logging
821         //
822         Logger.info("------------------------------------------------------------------------------------------------");
823         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
824                 Logger.metrics($params);
825                 Logger.metrics($manager);
826                 Logger.metrics($operation);
827                 Logger.metrics($opTimer);
828                 Logger.metrics($lock);
829                 //
830                 // Tell it its timed out
831                 //
832                 $operation.setOperationHasTimedOut();
833                 //
834                 // Create a notification for it ("DB Write - end operation")
835                 //
836                 ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
837                 notification.from = "policy";
838                 notification.policyName = drools.getRule().getName();
839                 notification.policyScope = "${policyScope}";
840                 notification.policyVersion = "${policyVersion}";
841                 notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
842                 notification.message = $operation.getOperationHistory();
843                 notification.history = $operation.getHistory();
844                 //
845                 // Let interested parties know
846                 //
847                 Engine.deliver("UEB", "POLICY-CL-MGT", notification);
848                 //
849                 // Get rid of the timer
850                 //
851                 retract($opTimer);
852                 //
853                 // Ensure the operation is complete
854                 //
855                 if ($operation.isOperationComplete() == true) {
856                         //
857                         // It is complete, remove it from memory
858                         //
859                         retract($operation);
860                         //
861                         // Complete the operation
862                         //
863                         modify($manager) {finishOperation($operation)};
864                 } else {
865                         //
866                         // Just doing this will kick off the LOCKED rule again
867                         //
868                         modify($operation) {};
869                 }
870 end
871
872 /*
873 *
874 * This is the timer that manages the overall control loop timeout.
875 *
876 */
877 rule "${policyName}.EVENT.MANAGER.TIMEOUT"
878         timer (expr: $to )
879     when
880         $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
881         $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
882         $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
883         $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
884         $operations : LinkedList()
885                                         from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID ) )
886         $opTimers : LinkedList()
887                                         from collect( OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() ) )
888         $locks : LinkedList()
889                                         from collect( TargetLock (requestID == $event.requestID) )
890         then
891         //
892         // Logging
893         //
894         Logger.info("------------------------------------------------------------------------------------------------");
895         Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
896                 Logger.metrics($params);
897                 Logger.metrics($manager);
898                 Logger.metrics($clTimer);
899                 if ($operations == null) {
900                         Logger.info("no operations found");
901                 } else {
902                         Logger.info("found " + $operations.size() + " operations");
903                 }
904                 //
905                 // Tell the Event Manager it has timed out
906                 //
907                 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
908                 if (notification != null) {
909                         notification.from = "policy";
910                         notification.policyName = drools.getRule().getName();
911                         notification.policyScope = "${policyScope}";
912                         notification.policyVersion = "${policyVersion}";
913                         //
914                         // Let interested parties know
915                         //
916                         Engine.deliver("UEB", "POLICY-CL-MGT", notification);
917                 }
918                 //
919                 // Retract EVERYTHING
920                 //
921                 retract($event);
922                 retract($manager);
923                 retract($clTimer);
924                 if ($operations != null && $operations.size() > 0) {
925                         Iterator<ControlLoopOperationManager> iter = $operations.iterator();
926                         while (iter.hasNext()) {
927                                 ControlLoopOperationManager manager = iter.next();
928                                 retract(manager);
929                         }
930                 }
931                 if ($opTimers != null && $opTimers.size() > 0) {
932                         Iterator<OperationTimer> iter = $opTimers.iterator();
933                         while (iter.hasNext()) {
934                                 OperationTimer opTimer = iter.next();
935                                 retract(opTimer);
936                         }
937                 }
938                 if ($locks != null && $locks.size() > 0) {
939                         Iterator<TargetLock> iter = $locks.iterator();
940                         while (iter.hasNext()) {
941                                 TargetLock lock = iter.next();
942                                 //
943                                 // Ensure we release the lock
944                                 //
945                                 PolicyGuard.unlockTarget(lock);
946                                 //
947                                 //
948                                 //
949                                 retract(lock);
950                         }
951                 }
952 end