2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop;
23 import org.onap.policy.controlloop.params.ControlLoopParams;
24 import org.onap.policy.controlloop.VirtualControlLoopEvent;
25 import org.onap.policy.controlloop.VirtualControlLoopNotification;
26 import org.onap.policy.controlloop.ControlLoopEventStatus;
27 import org.onap.policy.controlloop.ControlLoopNotificationType;
28 import org.onap.policy.controlloop.ControlLoopLogger;
29 import org.onap.policy.controlloop.policy.PolicyResult;
30 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
31 import org.onap.policy.controlloop.policy.Policy;
32 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
33 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
34 import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager;
35 import org.onap.policy.controlloop.actor.so.SoActorServiceProvider;
36 import org.onap.policy.aai.AaiNqResponseWrapper;
37 import org.onap.policy.appc.Request;
38 import org.onap.policy.appc.Response;
39 import org.onap.policy.appc.CommonHeader;
40 import org.onap.policy.appclcm.LcmRequestWrapper;
41 import org.onap.policy.appclcm.LcmResponseWrapper;
42 import org.onap.policy.appclcm.LcmRequest;
43 import org.onap.policy.appclcm.LcmResponse;
44 import org.onap.policy.appclcm.LcmCommonHeader;
45 import org.onap.policy.sdnr.PciRequestWrapper;
46 import org.onap.policy.sdnr.PciResponseWrapper;
47 import org.onap.policy.sdnr.PciRequest;
48 import org.onap.policy.sdnr.PciResponse;
49 import org.onap.policy.vfc.VFCRequest;
50 import org.onap.policy.vfc.VFCResponse;
51 import org.onap.policy.vfc.VFCManager;
52 import org.onap.policy.so.SOManager;
53 import org.onap.policy.so.SORequest;
54 import org.onap.policy.so.SORequestStatus;
55 import org.onap.policy.so.SORequestDetails;
56 import org.onap.policy.so.SOModelInfo;
57 import org.onap.policy.so.SOCloudConfiguration;
58 import org.onap.policy.so.SORequestInfo;
59 import org.onap.policy.so.SORequestParameters;
60 import org.onap.policy.so.SORelatedInstanceListElement;
61 import org.onap.policy.so.SORelatedInstance;
62 import org.onap.policy.so.SOResponse;
63 import org.onap.policy.so.SOResponseWrapper;
64 import org.onap.policy.sdnc.SdncRequest;
65 import org.onap.policy.sdnc.SdncManager;
66 import org.onap.policy.sdnc.SdncResponse;
67 import org.onap.policy.guard.PolicyGuard;
68 import org.onap.policy.guard.PolicyGuard.LockResult;
69 import org.onap.policy.guard.TargetLock;
70 import org.onap.policy.guard.GuardResult;
71 import org.onap.policy.guard.PolicyGuardRequest;
72 import org.onap.policy.guard.PolicyGuardResponse;
73 import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes;
74 import org.onap.policy.guard.PolicyGuardXacmlHelper;
76 import org.yaml.snakeyaml.Yaml;
77 import org.yaml.snakeyaml.constructor.Constructor;
79 import org.slf4j.LoggerFactory;
80 import org.slf4j.Logger;
82 import java.time.Instant;
83 import java.util.LinkedList;
84 import java.util.Iterator;
86 import org.onap.policy.drools.system.PolicyEngine;
89 * This object is to provide support for timeouts
90 * due to a bug in drools' built-in timers
92 declare ControlLoopTimer
93 closedLoopControlName : String
97 //timerType is the type of timer: either "ClosedLoop" or "Operation"
103 * Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW.
108 $params : ControlLoopParams()
111 // Note: globals have bad behavior when persistence is used,
112 // hence explicitly getting the logger vs using a global
114 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
115 logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "."
116 + drools.getRule().getName(), $params.getControlLoopYaml());
121 * This rule responds to DCAE Events where there is no manager yet. Either it is
122 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
127 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
128 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
129 not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
130 requestID == $event.getRequestId() ) )
133 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
134 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
139 // Check the event, because we need it to not be null when
140 // we create the ControlLoopEventManager. The ControlLoopEventManager
141 // will do extra syntax checking as well check if the closed loop is disabled.
143 if ($event.getRequestId() == null) {
144 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
145 notification.setNotification(ControlLoopNotificationType.REJECTED);
146 notification.setFrom("policy");
147 notification.setMessage("Missing requestID");
148 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
149 notification.setPolicyScope($params.getPolicyScope());
150 notification.setPolicyVersion($params.getPolicyVersion());
153 // Let interested parties know
155 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
158 // Retract it from memory
161 } else if ($event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET) {
162 throw new ControlLoopException($event.getClosedLoopEventStatus() + " received with no prior onset");
165 // Create an EventManager
167 ControlLoopEventManager manager = new ControlLoopEventManager($clName, $event.getRequestId());
169 // Determine if EventManager can actively process the event
170 // (i.e. syntax, is_closed_loop_disabled checks etc.)
172 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
173 notification.setFrom("pdp-0001-controller=controlloop"); // Engine.getInstanceName()
174 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
175 notification.setPolicyScope($params.getPolicyScope());
176 notification.setPolicyVersion($params.getPolicyVersion());
178 // Are we actively pursuing this event?
180 if (notification.getNotification() == ControlLoopNotificationType.ACTIVE) {
182 // Insert Event Manager into memory, this will now kick off processing.
186 // Let interested parties know
188 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
190 // Setup the Overall Control Loop timer
192 ControlLoopTimer clTimer = new ControlLoopTimer();
193 clTimer.setTimerType("ClosedLoop");
194 clTimer.setClosedLoopControlName($event.getClosedLoopControlName());
195 clTimer.setRequestID($event.getRequestId().toString());
196 clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
203 // Let interested parties know
205 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
207 // Retract it from memory
213 // Now that the manager is inserted into Drools working memory, we'll wait for
214 // another rule to fire in order to continue processing. This way we can also
215 // then screen for additional ONSET and ABATED events for this RequestID.
218 } catch (Exception e) {
219 logger.warn("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), e);
221 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
222 notification.setNotification(ControlLoopNotificationType.REJECTED);
223 notification.setMessage("Exception occurred: " + e.getMessage());
224 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
225 notification.setPolicyScope($params.getPolicyScope());
226 notification.setPolicyVersion($params.getPolicyVersion());
230 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
240 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
241 * is now created. We can start processing the yaml specification via the Event Manager.
246 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
247 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
248 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
249 requestID == $event.getRequestId() )
250 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
251 requestID == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired )
254 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
255 logger.info("{}: {}: event={} manager={} clTimer={}",
256 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
257 $event, $manager, $clTimer);
261 // Check which event this is.
263 ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
265 // Check what kind of event this is
267 if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
269 // We don't care about subsequent onsets
271 logger.info("{}: {}: subsequent onset",
272 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
276 if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
278 // Ignore any bad syntax events
280 logger.warn("{}: {}: syntax error",
281 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
286 // We only want the initial ONSET event in memory,
287 // all the other events need to be retracted to support
288 // cleanup and avoid the other rules being fired for this event.
290 if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
291 logger.warn("{}: {}: no first onset",
292 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
296 logger.debug("{}: {}: target={}", $clName,
297 $params.getPolicyName() + "." + drools.getRule().getName(), $event.getTarget());
299 // Now start seeing if we need to process this event
303 // Check if this is a Final Event
305 VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
308 if (notification != null) {
310 // Its final, but are we waiting for abatement?
312 if ($manager.getNumAbatements() > 0) {
313 logger.info("{}: {}: abatement received for {}. Closing the control loop",
314 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
315 $event.getRequestId());
316 notification.setFrom("policy");
317 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
318 notification.setPolicyScope($params.getPolicyScope());
319 notification.setPolicyVersion($params.getPolicyVersion());
321 // In this case, we are done
323 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
327 TargetLock lock = $manager.unlockCurrentOperation();
329 logger.debug("{}: {}: retracting lock=", $clName,
330 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
334 // Retract everything from memory
336 logger.info("{}: {}: retracting onset, manager, and timer",
337 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
339 retract($manager.getOnsetEvent());
343 // TODO - what if we get subsequent Events for this RequestID?
344 // By default, it will all start over again. May be confusing for Ruby.
345 // Or, we could track this and then subsequently ignore the events
349 // Check whether we need to wait for abatement
351 if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) {
352 logger.info("{}: {}: waiting for abatement ..",
353 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
355 logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
356 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
357 $event.getRequestId());
359 notification.setFrom("policy");
360 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
361 notification.setPolicyScope($params.getPolicyScope());
362 notification.setPolicyVersion($params.getPolicyVersion());
365 // In this case, we are done
367 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
371 TargetLock lock = $manager.unlockCurrentOperation();
373 logger.debug("{}: {}: retracting lock=", $clName,
374 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
378 // Retract everything from memory
380 logger.info("{}: {}: retracting onset, manager, and timer",
381 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
383 retract($manager.getOnsetEvent());
390 // NOT final, so let's ask for the next operation
392 ControlLoopOperationManager operation = $manager.processControlLoop();
393 if (operation != null) {
395 // Let's ask for a lock right away
397 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
398 logger.info("{}: {}: guard lock acquired={}",
399 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
401 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
403 // insert the operation into memory
408 // insert operation timeout object
410 ControlLoopTimer opTimer = new ControlLoopTimer();
411 opTimer.setTimerType("Operation");
412 opTimer.setClosedLoopControlName($event.getClosedLoopControlName());
413 opTimer.setRequestID($event.getRequestId().toString());
414 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
418 // Insert lock into memory
420 insert(result.getB());
423 logger.debug("The target resource {} is already processing",
424 $event.getAai().get($event.getTarget()));
425 notification = new VirtualControlLoopNotification($event);
426 notification.setNotification(ControlLoopNotificationType.REJECTED);
427 notification.setMessage("The target " + $event.getAai().get($event.getTarget())
428 + " is already locked");
429 notification.setFrom("policy");
430 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
431 notification.setPolicyScope($params.getPolicyScope());
432 notification.setPolicyVersion($params.getPolicyVersion());
434 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
440 if(result.getB() != null) {
441 retract(result.getB());
444 logger.info("{}: {}: starting operation={}",
445 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
449 // Probably waiting for abatement
451 logger.info("{}: {}: no operation, probably waiting for abatement",
452 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
455 } catch (Exception e) {
456 logger.warn("{}: {}: unexpected",
458 $params.getPolicyName() + "." + drools.getRule().getName(), e);
460 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
461 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
462 notification.setMessage(e.getMessage());
463 notification.setFrom("policy");
464 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
465 notification.setPolicyScope($params.getPolicyScope());
466 notification.setPolicyVersion($params.getPolicyVersion());
468 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
479 * Guard Permitted, let's send request to the actor.
482 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
484 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
485 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
486 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
487 requestID == $event.getRequestId() )
488 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
489 onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
490 $lock : TargetLock (requestID == $event.getRequestId())
491 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
492 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
495 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
496 logger.info("{}: {}: event={} manager={} operation={} lock={}",
497 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
498 $event, $manager, $operation, $lock);
500 Object request = null;
501 boolean caughtException = false;
504 request = $operation.startOperation($event);
506 if (request != null) {
507 logger.debug("{}: {}: starting operation ..",
509 $params.getPolicyName() + "." + drools.getRule().getName());
511 // Tell interested parties we are performing this Operation
513 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
514 notification.setNotification(ControlLoopNotificationType.OPERATION);
515 notification.setMessage($operation.getOperationMessage());
516 notification.setHistory($operation.getHistory());
517 notification.setFrom("policy");
518 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
519 notification.setPolicyScope($params.getPolicyScope());
520 notification.setPolicyVersion($params.getPolicyVersion());
522 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
524 switch ($operation.policy.getActor()){
528 if (request instanceof Request) {
529 PolicyEngine.manager.deliver("APPC-CL", request);
531 else if (request instanceof LcmRequestWrapper) {
532 PolicyEngine.manager.deliver("APPC-LCM-READ", request);
536 // at this point the AAI named query request should have already been made, the response
537 // recieved and used in the construction of the SO Request which is stored in operationRequest
539 if(request instanceof SORequest) {
540 // Call SO. The response will be inserted into memory once it's received
541 SoActorServiceProvider.sendRequest($event.getRequestId().toString(), drools.getWorkingMemory(), request);
545 if (request instanceof VFCRequest) {
547 Thread t = new Thread(new VFCManager(drools.getWorkingMemory(), (VFCRequest)request));
552 if (request instanceof PciRequestWrapper) {
553 PolicyEngine.manager.deliver("SDNR-CL", request);
558 if (request instanceof SdncRequest) {
560 Thread t = new Thread(new SdncManager(drools.getWorkingMemory(), (SdncRequest)request));
567 // What happens if its null?
569 logger.warn("{}: {}: unexpected null operation request",
571 $params.getPolicyName() + "." + drools.getRule().getName());
572 if ("SO".equals($operation.policy.getActor())) {
575 modify($manager) {finishOperation($operation)};
577 else if ("vfc".equalsIgnoreCase($operation.policy.getActor())) {
580 modify($manager) {finishOperation($operation)};
584 } catch (Exception e) {
585 String msg = e.getMessage();
586 logger.warn("{}: {}: operation={}: AAI failure: {}",
588 $params.getPolicyName() + "." + drools.getRule().getName(),
590 $operation.setOperationHasException(msg);
592 if(request != null) {
594 // Create a notification for it ("DB Write - end operation")
596 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
597 notification.setFrom("policy");
598 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
599 notification.setPolicyScope($params.getPolicyScope());
600 notification.setPolicyVersion($params.getPolicyVersion());
601 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
602 notification.setMessage($operation.getOperationHistory());
603 notification.setHistory($operation.getHistory());
605 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
610 caughtException = true;
613 // Having the modify statement in the catch clause doesn't work for whatever reason
614 if (caughtException) {
615 modify($manager) {finishOperation($operation)};
622 * We were able to acquire a lock so now let's ask Xacml Guard whether
623 * we are allowed to proceed with the request to the actor.
626 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
628 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
629 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
630 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
631 requestID == $event.getRequestId() )
632 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
633 onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" )
634 $lock : TargetLock (requestID == $event.getRequestId())
637 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
638 logger.info("{}: {}: event={} manager={} operation={} lock={}",
639 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
640 $event, $manager, $operation, $lock);
643 // Sending notification that we are about to query Guard ("DB write - start operation")
645 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
646 notification.setNotification(ControlLoopNotificationType.OPERATION);
647 notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " "
648 + $operation.policy.getRecipe());
649 notification.setHistory($operation.getHistory());
650 notification.setFrom("policy");
651 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
652 notification.setPolicyScope($params.getPolicyScope());
653 notification.setPolicyVersion($params.getPolicyVersion());
655 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
658 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
659 // just change guardEnabled to false.
661 // In order to use REST XACML, provide a URL instead of "" as a second argument
662 // to the CallGuardTask() and set the first argument to null
663 // (instead of XacmlPdpEngine).
666 // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
667 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
671 Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
672 drools.getWorkingMemory(),
673 $event.getClosedLoopControlName(),
674 $operation.policy.getActor().toString(),
675 $operation.policy.getRecipe(),
676 $operation.getTargetEntity(),
677 $event.getRequestId().toString(),
679 AaiNqResponseWrapper resp = $manager.getNqVserverFromAai();
680 return(resp == null ? null : resp.countVfModules());
685 insert(new PolicyGuardResponse("Permit", $event.getRequestId(), $operation.policy.getRecipe()));
691 // This rule will be triggered when a thread talking to the XACML Guard inserts a
692 // guardResponse object into the working memory
694 rule "GUARD.RESPONSE"
696 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
697 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
698 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
699 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
700 requestID == $event.getRequestId() )
701 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
702 onset.getRequestId() == $event.getRequestId() )
703 $lock : TargetLock (requestID == $event.getRequestId())
704 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
705 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
706 $guardResponse : PolicyGuardResponse(requestID == $event.getRequestId(), $operation.policy.recipe == operation)
709 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
710 logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
711 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
712 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
715 //we will permit the operation if there was no Guard for it
716 if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){
717 $guardResponse.setResult("Permit");
721 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
723 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
724 notification.setNotification(ControlLoopNotificationType.OPERATION);
725 notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()
726 + " is " + $guardResponse.getResult());
727 notification.setHistory($operation.getHistory());
728 notification.setFrom("policy");
729 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
730 notification.setPolicyScope($params.getPolicyScope());
731 notification.setPolicyVersion($params.getPolicyVersion());
733 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
735 if("Permit".equalsIgnoreCase($guardResponse.getResult())){
737 modify($operation){setGuardApprovalStatus($guardResponse.getResult())};
740 //This is the Deny case
741 $operation.startOperation($event);
742 $operation.setOperationHasGuardDeny();
745 modify($manager) {finishOperation($operation)};
748 retract($guardResponse);
754 * This rule responds to APPC Response Events
756 * I would have like to be consistent and write the Response like this:
757 * $response : Response( CommonHeader.RequestId == $onset.getRequestId() )
759 * However, no compile error was given. But a runtime error was given. I think
760 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
765 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
766 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
767 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
768 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
769 requestID == $event.getRequestId() )
770 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
771 onset.getRequestId() == $event.getRequestId() )
772 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
773 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
774 $lock : TargetLock (requestID == $event.getRequestId())
775 $response : Response( getCommonHeader().RequestId == $event.getRequestId() )
778 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
779 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
780 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
781 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
782 $event, $manager, $operation, $lock, $opTimer, $response);
784 // Get the result of the operation
786 PolicyResult policyResult = $operation.onResponse($response);
787 if (policyResult != null) {
788 logger.debug("{}: {}: operation finished - result={}",
789 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
792 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
794 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
795 notification.setFrom("policy");
796 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
797 notification.setPolicyScope($params.getPolicyScope());
798 notification.setPolicyVersion($params.getPolicyVersion());
799 notification.setMessage($operation.getOperationHistory());
800 notification.setHistory($operation.getHistory());
801 if (policyResult.equals(PolicyResult.SUCCESS)) {
802 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
804 // Let interested parties know
806 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
808 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
810 // Let interested parties know
812 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
815 // Ensure the operation is complete
817 if ($operation.isOperationComplete() == true) {
819 // It is complete, remove it from memory
823 // We must also retract the timer object
824 // NOTE: We could write a Rule to do this
828 // Complete the operation
830 modify($manager) {finishOperation($operation)};
833 // Just doing this will kick off the LOCKED rule again
835 modify($operation) {};
839 // Its not finished yet (i.e. expecting more Response objects)
841 // Or possibly it is a leftover response that we timed the request out previously
845 // We are going to retract these objects from memory
852 * The problem with Responses is that they don't have a controlLoopControlName
853 * field in them, so the only way to attach them is via RequestID. If we have multiple
854 * control loop .drl's loaded in the same container, we need to be sure the cleanup
855 * rules don't remove Responses for other control loops.
858 rule "APPC.RESPONSE.CLEANUP"
860 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
861 $response : Response($id : getCommonHeader().RequestId )
862 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
865 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
866 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
867 logger.debug("{}: {}: orphan appc response={}",
868 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
878 * This rule responds to APPC Response Events using the new LCM interface provided by appc
881 rule "APPC.LCM.RESPONSE"
883 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
884 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
885 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
886 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
887 requestID == $event.getRequestId() )
888 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
889 onset.getRequestId() == $event.getRequestId() )
890 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
891 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
892 $lock : TargetLock (requestID == $event.getRequestId())
893 $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
896 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
897 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
898 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
899 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
900 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
903 // Get the result of the operation
905 PolicyResult policyResult = $operation.onResponse($response);
906 if (policyResult != null) {
907 logger.debug("{}: {}: operation finished - result={}",
908 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
912 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
914 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
915 notification.setFrom("policy");
916 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
917 notification.setPolicyScope($params.getPolicyScope());
918 notification.setPolicyVersion($params.getPolicyVersion());
919 notification.setMessage($operation.getOperationHistory());
920 notification.setHistory($operation.getHistory());
921 if (policyResult.equals(PolicyResult.SUCCESS)) {
922 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
924 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
926 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
928 // Ensure the operation is complete
930 if ($operation.isOperationComplete() == true) {
932 // It is complete, remove it from memory
936 // We must also retract the timer object
937 // NOTE: We could write a Rule to do this
941 // Complete the operation
943 modify($manager) {finishOperation($operation)};
946 // Just doing this will kick off the LOCKED rule again
948 modify($operation) {};
952 // Its not finished yet (i.e. expecting more Response objects)
954 // Or possibly it is a leftover response that we timed the request out previously
958 // We are going to retract these objects from memory
965 * Clean Up any lingering LCM reponses
968 rule "APPC.LCM.RESPONSE.CLEANUP"
970 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
971 $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId )
972 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
975 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
976 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
977 logger.debug("{}: {}: orphan appc response={}",
978 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
987 * This rule responds to SO Response Events
992 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
993 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
994 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
995 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
996 requestID == $event.getRequestId() )
997 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
998 onset.getRequestId() == $event.getRequestId() )
999 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1000 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1001 $lock : TargetLock (requestID == $event.getRequestId())
1002 $response : SOResponseWrapper(requestID.toString() == $event.getRequestId().toString() )
1005 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1006 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1007 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1008 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1009 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1011 // Get the result of the operation
1013 PolicyResult policyResult = $operation.onResponse($response);
1014 if (policyResult != null) {
1015 logger.debug("{}: {}: operation finished - result={}",
1016 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1020 // This Operation has completed, construct a notification showing our results
1022 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1023 notification.setFrom("policy");
1024 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1025 notification.setPolicyScope($params.getPolicyScope());
1026 notification.setPolicyVersion($params.getPolicyVersion());
1027 notification.setMessage($operation.getOperationHistory());
1028 notification.setHistory($operation.getHistory());
1029 if (policyResult.equals(PolicyResult.SUCCESS)) {
1030 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1032 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1035 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1037 // Ensure the operation is complete
1039 if ($operation.isOperationComplete() == true) {
1041 // It is complete, remove it from memory
1043 retract($operation);
1045 // We must also retract the timer object
1046 // NOTE: We could write a Rule to do this
1050 // Complete the operation
1052 modify($manager) {finishOperation($operation)};
1055 // Just doing this will kick off the LOCKED rule again
1057 modify($operation) {};
1061 // Its not finished yet (i.e. expecting more Response objects)
1063 // Or possibly it is a leftover response that we timed the request out previously
1067 // We are going to retract these objects from memory
1075 * This rule responds to VFC Response Events
1080 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1081 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1082 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1083 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1084 requestID == $event.getRequestId() )
1085 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1086 onset.getRequestId() == $event.getRequestId() )
1087 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1088 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1089 $lock : TargetLock (requestID == $event.getRequestId())
1090 $response : VFCResponse( requestId.toString() == $event.getRequestId().toString() )
1092 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1093 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1094 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1095 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1096 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1098 // Get the result of the operation
1100 PolicyResult policyResult = $operation.onResponse($response);
1101 if (policyResult != null) {
1103 // This Operation has completed, construct a notification showing our results
1105 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1106 notification.setFrom("policy");
1107 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1108 notification.setPolicyScope($params.getPolicyScope());
1109 notification.setPolicyVersion($params.getPolicyVersion());
1110 notification.setMessage($operation.getOperationHistory());
1111 notification.setHistory($operation.getHistory());
1113 // Ensure the operation is complete
1115 if ($operation.isOperationComplete() == true) {
1117 // It is complete, remove it from memory
1119 retract($operation);
1121 // We must also retract the timer object
1122 // NOTE: We could write a Rule to do this
1126 // Complete the operation
1128 modify($manager) {finishOperation($operation)};
1131 // Just doing this will kick off the LOCKED rule again
1133 modify($operation) {};
1137 // Its not finished yet (i.e. expecting more Response objects)
1139 // Or possibly it is a leftover response that we timed the request out previously
1143 // We are going to retract these objects from memory
1151 * This rule responds to SDNC Response Events
1154 rule "SDNC.RESPONSE"
1156 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1157 $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1158 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestID == $event.getRequestId() )
1159 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() )
1160 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1161 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1162 $lock : TargetLock (requestID == $event.getRequestId())
1163 $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() )
1165 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1166 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1167 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1168 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1169 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1171 // Get the result of the operation
1173 PolicyResult policyResult = $operation.onResponse($response);
1174 if (policyResult != null) {
1176 // This Operation has completed, construct a notification showing our results
1178 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1179 notification.setFrom("policy");
1180 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1181 notification.setPolicyScope($params.getPolicyScope());
1182 notification.setPolicyVersion($params.getPolicyVersion());
1183 notification.setMessage($operation.getOperationHistory());
1184 notification.setHistory($operation.getHistory());
1186 // Ensure the operation is complete
1188 if ($operation.isOperationComplete()) {
1190 // It is complete, remove it from memory
1192 retract($operation);
1194 // We must also retract the timer object
1195 // NOTE: We could write a Rule to do this
1199 // Complete the operation
1201 modify($manager) {finishOperation($operation)};
1204 // Just doing this will kick off the LOCKED rule again
1206 modify($operation) {};
1210 // Its not finished yet (i.e. expecting more Response objects)
1212 // Or possibly it is a leftover response that we timed the request out previously
1216 // We are going to retract these objects from memory
1224 * This manages a single timer.
1225 * Due to a bug in the drools code, the drools timer needed to be split from most of the objects in the when clause
1229 timer (expr: $timeout)
1231 $timer : ControlLoopTimer($timeout : delay, !expired)
1233 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1234 logger.info("This is TIMER.FIRED");
1235 modify($timer){setExpired(true)};
1240 * This is the timer that manages the timeout for an individual operation.
1243 rule "EVENT.MANAGER.OPERATION.TIMEOUT"
1245 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1246 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1247 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1248 requestID == $event.getRequestId() )
1249 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1250 onset.getRequestId() == $event.getRequestId() )
1251 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1252 requestID == $event.getRequestId().toString(), timerType == "Operation", expired )
1253 $lock : TargetLock (requestID == $event.getRequestId())
1256 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1257 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1258 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
1259 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1260 $event, $manager, $operation, $lock, $operation, $opTimer);
1263 // Tell it its timed out
1265 $operation.setOperationHasTimedOut();
1267 // Create a notification for it ("DB Write - end operation")
1269 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1270 notification.setFrom("policy");
1271 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1272 notification.setPolicyScope($params.getPolicyScope());
1273 notification.setPolicyVersion($params.getPolicyVersion());
1274 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1275 notification.setMessage($operation.getOperationHistory());
1276 notification.setHistory($operation.getHistory());
1278 // Let interested parties know
1280 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1282 // Get rid of the timer
1286 // Ensure the operation is complete
1288 if ($operation.isOperationComplete() == true) {
1290 // It is complete, remove it from memory
1292 retract($operation);
1294 // Complete the operation
1296 modify($manager) {finishOperation($operation)};
1299 // Just doing this will kick off the LOCKED rule again
1301 modify($operation) {};
1307 * This is the timer that manages the overall control loop timeout.
1310 rule "EVENT.MANAGER.TIMEOUT"
1312 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1313 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1314 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1315 requestID == $event.getRequestId() )
1316 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1317 requestID == $event.getRequestId().toString(), timerType == "ClosedLoop", expired )
1320 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1321 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1323 logger.debug("{}: {}: event={}",
1324 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1327 // Tell the Event Manager it has timed out
1329 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
1330 if (notification != null) {
1331 notification.setFrom("policy");
1332 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1333 notification.setPolicyScope($params.getPolicyScope());
1334 notification.setPolicyVersion($params.getPolicyVersion());
1336 // Let interested parties know
1338 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1341 // Retract the event
1348 * This rule cleans up the manager and other objects after an event has
1352 rule "EVENT.MANAGER.CLEANUP"
1354 $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestID() )
1355 $operations : LinkedList()
1356 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName,
1357 onset.getRequestId() == $requestId ) )
1358 $timers : LinkedList()
1359 from collect( ControlLoopTimer( closedLoopControlName == $clName,
1360 requestID == $requestId.toString() ) )
1361 $locks : LinkedList()
1362 from collect( TargetLock (requestID == $requestId) )
1363 not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) )
1366 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1367 logger.info("{}: {}", $clName, drools.getRule().getName());
1369 logger.debug("{}: {}: manager={} timers={} operations={}",
1370 $clName, drools.getRule().getName(),
1371 $manager, $timers.size(), $operations.size());
1374 // Retract EVERYTHING
1378 for(Object manager: $operations) {
1379 retract((ControlLoopOperationManager) manager);
1381 for(Object timer: $timers) {
1382 retract((ControlLoopTimer) timer);
1384 for(Object lock: $locks) {
1385 TargetLock tgt = (TargetLock) lock;
1387 // Ensure we release the lock
1389 PolicyGuard.unlockTarget(tgt);
1396 * This rule will clean up any rogue onsets where there is no
1397 * ControlLoopParams object corresponding to the onset event.
1400 rule "EVENT.CLEANUP"
1402 $event : VirtualControlLoopEvent( $clName: closedLoopControlName )
1403 not ( ControlLoopParams( getClosedLoopControlName() == $clName) )
1406 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1407 logger.info("{}: {}", $clName, drools.getRule().getName());
1408 logger.debug("{}: {}: orphan onset event={}",
1409 $clName, drools.getRule().getName(), $event);
1416 * This rule responds to SDNR Response Events.
1419 rule "SDNR.RESPONSE"
1421 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1422 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1423 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1424 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1425 requestID == $event.getRequestId() )
1426 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1427 onset.getRequestId() == $event.getRequestId() )
1428 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1429 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1430 $lock : TargetLock (requestID == $event.getRequestId())
1431 $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
1434 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1435 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1436 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1437 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1438 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1441 // Get the result of the operation
1443 PolicyResult policyResult = $operation.onResponse($response);
1444 if (policyResult != null) {
1445 logger.debug("{}: {}: operation finished - result={}",
1446 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1450 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
1452 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1453 notification.setFrom("policy");
1454 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1455 notification.setPolicyScope($params.getPolicyScope());
1456 notification.setPolicyVersion($params.getPolicyVersion());
1457 notification.setMessage($operation.getOperationHistory());
1458 notification.setHistory($operation.getHistory());
1459 if (policyResult.equals(PolicyResult.SUCCESS)) {
1460 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1462 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1464 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1466 // Ensure the operation is complete
1468 if ($operation.isOperationComplete() == true) {
1470 // It is complete, remove it from memory
1472 retract($operation);
1474 // We must also retract the timer object
1475 // NOTE: We could write a Rule to do this
1479 // Complete the operation
1481 modify($manager) {finishOperation($operation)};
1484 // Just doing this will kick off the LOCKED rule again
1486 modify($operation) {};
1490 // Its not finished yet (i.e. expecting more Response objects)
1492 // Or possibly it is a leftover response that we timed the request out previously
1496 // We are going to retract these objects from memory
1503 * Clean Up any lingering SDNR reponses.
1506 rule "SDNR.RESPONSE.CLEANUP"
1508 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1509 $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1510 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1513 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1514 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1515 logger.debug("{}: {}: orphan sdnr response={}",
1516 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);