2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-2019 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());
341 // don't retract manager, etc. - a clean-up rule will do that
344 // TODO - what if we get subsequent Events for this RequestID?
345 // By default, it will all start over again. May be confusing for Ruby.
346 // Or, we could track this and then subsequently ignore the events
350 // Check whether we need to wait for abatement
352 if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) {
353 logger.info("{}: {}: waiting for abatement ..",
354 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
356 logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
357 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
358 $event.getRequestId());
360 notification.setFrom("policy");
361 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
362 notification.setPolicyScope($params.getPolicyScope());
363 notification.setPolicyVersion($params.getPolicyVersion());
366 // In this case, we are done
368 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
372 TargetLock lock = $manager.unlockCurrentOperation();
374 logger.debug("{}: {}: retracting lock=", $clName,
375 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
379 // Retract everything from memory
381 logger.info("{}: {}: retracting onset, manager, and timer",
382 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
384 retract($manager.getOnsetEvent());
386 // don't retract manager, etc. - a clean-up rule will do that
391 // NOT final, so let's ask for the next operation
393 ControlLoopOperationManager operation = $manager.processControlLoop();
394 if (operation != null) {
396 // Let's ask for a lock right away
398 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
399 logger.info("{}: {}: guard lock acquired={}",
400 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
402 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
404 // insert the operation into memory
409 // insert operation timeout object
411 ControlLoopTimer opTimer = new ControlLoopTimer();
412 opTimer.setTimerType("Operation");
413 opTimer.setClosedLoopControlName($event.getClosedLoopControlName());
414 opTimer.setRequestID($event.getRequestId().toString());
415 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
419 // Insert lock into memory
421 insert(result.getB());
424 logger.debug("The target resource {} is already processing",
425 $event.getAai().get($event.getTarget()));
426 notification = new VirtualControlLoopNotification($event);
427 notification.setNotification(ControlLoopNotificationType.REJECTED);
428 notification.setMessage("The target " + $event.getAai().get($event.getTarget())
429 + " is already locked");
430 notification.setFrom("policy");
431 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
432 notification.setPolicyScope($params.getPolicyScope());
433 notification.setPolicyVersion($params.getPolicyVersion());
435 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
439 // don't retract manager, etc. - a clean-up rule will do that
441 if(result.getB() != null) {
442 retract(result.getB());
445 logger.info("{}: {}: starting operation={}",
446 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
450 // Probably waiting for abatement
452 logger.info("{}: {}: no operation, probably waiting for abatement",
453 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
456 } catch (Exception e) {
457 logger.warn("{}: {}: unexpected",
459 $params.getPolicyName() + "." + drools.getRule().getName(), e);
461 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
462 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
463 notification.setMessage(e.getMessage());
464 notification.setFrom("policy");
465 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
466 notification.setPolicyScope($params.getPolicyScope());
467 notification.setPolicyVersion($params.getPolicyVersion());
469 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
473 // don't retract manager, etc. - a clean-up rule will do that
480 * Guard Permitted, let's send request to the actor.
483 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
485 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
486 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
487 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
488 requestID == $event.getRequestId() )
489 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
490 onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
491 $lock : TargetLock (requestID == $event.getRequestId())
492 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
493 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
496 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
497 logger.info("{}: {}: event={} manager={} operation={} lock={}",
498 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
499 $event, $manager, $operation, $lock);
501 Object request = null;
502 boolean caughtException = false;
505 request = $operation.startOperation($event);
507 if (request != null) {
508 logger.debug("{}: {}: starting operation ..",
510 $params.getPolicyName() + "." + drools.getRule().getName());
512 // Tell interested parties we are performing this Operation
514 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
515 notification.setNotification(ControlLoopNotificationType.OPERATION);
516 notification.setMessage($operation.getOperationMessage());
517 notification.setHistory($operation.getHistory());
518 notification.setFrom("policy");
519 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
520 notification.setPolicyScope($params.getPolicyScope());
521 notification.setPolicyVersion($params.getPolicyVersion());
523 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
525 switch ($operation.policy.getActor()){
529 if (request instanceof Request) {
530 PolicyEngine.manager.deliver("APPC-CL", request);
532 else if (request instanceof LcmRequestWrapper) {
533 PolicyEngine.manager.deliver("APPC-LCM-READ", request);
537 // at this point the AAI named query request should have already been made, the response
538 // recieved and used in the construction of the SO Request which is stored in operationRequest
540 if(request instanceof SORequest) {
541 // Call SO. The response will be inserted into memory once it's received
542 SoActorServiceProvider.sendRequest($event.getRequestId().toString(), drools.getWorkingMemory(), request);
546 if (request instanceof VfcRequest) {
548 Thread t = new Thread(new VfcManager(drools.getWorkingMemory(), (VfcRequest)request));
553 if (request instanceof PciRequestWrapper) {
554 PolicyEngine.manager.deliver("SDNR-CL", request);
559 if (request instanceof SdncRequest) {
561 Thread t = new Thread(new SdncManager(drools.getWorkingMemory(), (SdncRequest)request));
568 // What happens if its null?
570 logger.warn("{}: {}: unexpected null operation request",
572 $params.getPolicyName() + "." + drools.getRule().getName());
573 if ("SO".equals($operation.policy.getActor())) {
576 modify($manager) {finishOperation($operation)};
578 else if ("vfc".equalsIgnoreCase($operation.policy.getActor())) {
581 modify($manager) {finishOperation($operation)};
583 else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) {
586 modify($manager) {finishOperation($operation)};
590 } catch (Exception e) {
591 String msg = e.getMessage();
592 logger.warn("{}: {}: operation={}: AAI failure: {}",
594 $params.getPolicyName() + "." + drools.getRule().getName(),
596 $operation.setOperationHasException(msg);
598 if(request != null) {
600 // Create a notification for it ("DB Write - end operation")
602 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
603 notification.setFrom("policy");
604 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
605 notification.setPolicyScope($params.getPolicyScope());
606 notification.setPolicyVersion($params.getPolicyVersion());
607 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
608 notification.setMessage($operation.getOperationHistory());
609 notification.setHistory($operation.getHistory());
611 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
616 caughtException = true;
619 // Having the modify statement in the catch clause doesn't work for whatever reason
620 if (caughtException) {
621 modify($manager) {finishOperation($operation)};
628 * We were able to acquire a lock so now let's ask Xacml Guard whether
629 * we are allowed to proceed with the request to the actor.
632 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
634 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
635 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
636 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
637 requestID == $event.getRequestId() )
638 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
639 onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" )
640 $lock : TargetLock (requestID == $event.getRequestId())
643 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
644 logger.info("{}: {}: event={} manager={} operation={} lock={}",
645 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
646 $event, $manager, $operation, $lock);
649 // Sending notification that we are about to query Guard ("DB write - start operation")
651 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
652 notification.setNotification(ControlLoopNotificationType.OPERATION);
653 notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " "
654 + $operation.policy.getRecipe());
655 notification.setHistory($operation.getHistory());
656 notification.setFrom("policy");
657 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
658 notification.setPolicyScope($params.getPolicyScope());
659 notification.setPolicyVersion($params.getPolicyVersion());
661 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
664 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
665 // just change guardEnabled to false.
667 // In order to use REST XACML, provide a URL instead of "" as a second argument
668 // to the CallGuardTask() and set the first argument to null
669 // (instead of XacmlPdpEngine).
672 // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
673 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
677 Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
678 drools.getWorkingMemory(),
679 $event.getClosedLoopControlName(),
680 $operation.policy.getActor().toString(),
681 $operation.policy.getRecipe(),
682 $operation.getTargetEntity(),
683 $event.getRequestId().toString(),
685 AaiNqResponseWrapper resp = $manager.getNqVserverFromAai();
686 return(resp == null ? null : resp.countVfModules());
691 insert(new PolicyGuardResponse("Permit", $event.getRequestId(), $operation.policy.getRecipe()));
697 // This rule will be triggered when a thread talking to the XACML Guard inserts a
698 // guardResponse object into the working memory
700 rule "GUARD.RESPONSE"
702 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
703 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
704 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
705 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
706 requestID == $event.getRequestId() )
707 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
708 onset.getRequestId() == $event.getRequestId() )
709 $lock : TargetLock (requestID == $event.getRequestId())
710 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
711 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
712 $guardResponse : PolicyGuardResponse(requestID == $event.getRequestId(), $operation.policy.recipe == operation)
715 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
716 logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
717 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
718 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
721 //we will permit the operation if there was no Guard for it
722 if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){
723 $guardResponse.setResult("Permit");
727 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
729 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
730 notification.setNotification(ControlLoopNotificationType.OPERATION);
731 notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()
732 + " is " + $guardResponse.getResult());
733 notification.setHistory($operation.getHistory());
734 notification.setFrom("policy");
735 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
736 notification.setPolicyScope($params.getPolicyScope());
737 notification.setPolicyVersion($params.getPolicyVersion());
739 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
741 if("Permit".equalsIgnoreCase($guardResponse.getResult())){
743 modify($operation){setGuardApprovalStatus($guardResponse.getResult())};
746 //This is the Deny case
747 $operation.startOperation($event);
748 $operation.setOperationHasGuardDeny();
751 modify($manager) {finishOperation($operation)};
754 retract($guardResponse);
760 * This rule responds to APPC Response Events
762 * I would have like to be consistent and write the Response like this:
763 * $response : Response( CommonHeader.RequestId == $onset.getRequestId() )
765 * However, no compile error was given. But a runtime error was given. I think
766 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
771 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
772 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
773 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
774 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
775 requestID == $event.getRequestId() )
776 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
777 onset.getRequestId() == $event.getRequestId() )
778 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
779 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
780 $lock : TargetLock (requestID == $event.getRequestId())
781 $response : Response( getCommonHeader().RequestId == $event.getRequestId() )
784 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
785 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
786 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
787 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
788 $event, $manager, $operation, $lock, $opTimer, $response);
790 // Get the result of the operation
792 PolicyResult policyResult = $operation.onResponse($response);
793 if (policyResult != null) {
794 logger.debug("{}: {}: operation finished - result={}",
795 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
798 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
800 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
801 notification.setFrom("policy");
802 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
803 notification.setPolicyScope($params.getPolicyScope());
804 notification.setPolicyVersion($params.getPolicyVersion());
805 notification.setMessage($operation.getOperationHistory());
806 notification.setHistory($operation.getHistory());
807 if (policyResult.equals(PolicyResult.SUCCESS)) {
808 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
810 // Let interested parties know
812 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
814 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
816 // Let interested parties know
818 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
821 // Ensure the operation is complete
823 if ($operation.isOperationComplete() == true) {
825 // It is complete, remove it from memory
829 // We must also retract the timer object
830 // NOTE: We could write a Rule to do this
834 // Complete the operation
836 modify($manager) {finishOperation($operation)};
839 // Just doing this will kick off the LOCKED rule again
841 modify($operation) {};
845 // Its not finished yet (i.e. expecting more Response objects)
847 // Or possibly it is a leftover response that we timed the request out previously
851 // We are going to retract these objects from memory
858 * The problem with Responses is that they don't have a controlLoopControlName
859 * field in them, so the only way to attach them is via RequestID. If we have multiple
860 * control loop .drl's loaded in the same container, we need to be sure the cleanup
861 * rules don't remove Responses for other control loops.
864 rule "APPC.RESPONSE.CLEANUP"
866 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
867 $response : Response($id : getCommonHeader().RequestId )
868 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
871 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
872 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
873 logger.debug("{}: {}: orphan appc response={}",
874 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
884 * This rule responds to APPC Response Events using the new LCM interface provided by appc
887 rule "APPC.LCM.RESPONSE"
889 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
890 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
891 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
892 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
893 requestID == $event.getRequestId() )
894 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
895 onset.getRequestId() == $event.getRequestId() )
896 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
897 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
898 $lock : TargetLock (requestID == $event.getRequestId())
899 $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
902 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
903 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
904 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
905 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
906 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
909 // Get the result of the operation
911 PolicyResult policyResult = $operation.onResponse($response);
912 if (policyResult != null) {
913 logger.debug("{}: {}: operation finished - result={}",
914 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
918 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
920 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
921 notification.setFrom("policy");
922 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
923 notification.setPolicyScope($params.getPolicyScope());
924 notification.setPolicyVersion($params.getPolicyVersion());
925 notification.setMessage($operation.getOperationHistory());
926 notification.setHistory($operation.getHistory());
927 if (policyResult.equals(PolicyResult.SUCCESS)) {
928 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
930 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
932 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
934 // Ensure the operation is complete
936 if ($operation.isOperationComplete() == true) {
938 // It is complete, remove it from memory
942 // We must also retract the timer object
943 // NOTE: We could write a Rule to do this
947 // Complete the operation
949 modify($manager) {finishOperation($operation)};
952 // Just doing this will kick off the LOCKED rule again
954 modify($operation) {};
958 // Its not finished yet (i.e. expecting more Response objects)
960 // Or possibly it is a leftover response that we timed the request out previously
964 // We are going to retract these objects from memory
971 * Clean Up any lingering LCM reponses
974 rule "APPC.LCM.RESPONSE.CLEANUP"
976 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
977 $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId )
978 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
981 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
982 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
983 logger.debug("{}: {}: orphan appc response={}",
984 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
993 * This rule responds to SO Response Events
998 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
999 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1000 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1001 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1002 requestID == $event.getRequestId() )
1003 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1004 onset.getRequestId() == $event.getRequestId() )
1005 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1006 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1007 $lock : TargetLock (requestID == $event.getRequestId())
1008 $response : SOResponseWrapper(requestID.toString() == $event.getRequestId().toString() )
1011 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1012 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1013 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1014 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1015 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1017 // Get the result of the operation
1019 PolicyResult policyResult = $operation.onResponse($response);
1020 if (policyResult != null) {
1021 logger.debug("{}: {}: operation finished - result={}",
1022 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1026 // This Operation has completed, construct a notification showing our results
1028 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1029 notification.setFrom("policy");
1030 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1031 notification.setPolicyScope($params.getPolicyScope());
1032 notification.setPolicyVersion($params.getPolicyVersion());
1033 notification.setMessage($operation.getOperationHistory());
1034 notification.setHistory($operation.getHistory());
1035 if (policyResult.equals(PolicyResult.SUCCESS)) {
1036 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1038 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1041 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1043 // Ensure the operation is complete
1045 if ($operation.isOperationComplete() == true) {
1047 // It is complete, remove it from memory
1049 retract($operation);
1051 // We must also retract the timer object
1052 // NOTE: We could write a Rule to do this
1056 // Complete the operation
1058 modify($manager) {finishOperation($operation)};
1061 // Just doing this will kick off the LOCKED rule again
1063 modify($operation) {};
1067 // Its not finished yet (i.e. expecting more Response objects)
1069 // Or possibly it is a leftover response that we timed the request out previously
1073 // We are going to retract these objects from memory
1081 * This rule responds to VFC Response Events
1086 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1087 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1088 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1089 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1090 requestID == $event.getRequestId() )
1091 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1092 onset.getRequestId() == $event.getRequestId() )
1093 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1094 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1095 $lock : TargetLock (requestID == $event.getRequestId())
1096 $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() )
1098 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1099 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1100 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1101 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1102 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1104 // Get the result of the operation
1106 PolicyResult policyResult = $operation.onResponse($response);
1107 if (policyResult != null) {
1109 // This Operation has completed, construct a notification showing our results
1111 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1112 notification.setFrom("policy");
1113 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1114 notification.setPolicyScope($params.getPolicyScope());
1115 notification.setPolicyVersion($params.getPolicyVersion());
1116 notification.setMessage($operation.getOperationHistory());
1117 notification.setHistory($operation.getHistory());
1119 // Ensure the operation is complete
1121 if ($operation.isOperationComplete() == true) {
1123 // It is complete, remove it from memory
1125 retract($operation);
1127 // We must also retract the timer object
1128 // NOTE: We could write a Rule to do this
1132 // Complete the operation
1134 modify($manager) {finishOperation($operation)};
1137 // Just doing this will kick off the LOCKED rule again
1139 modify($operation) {};
1143 // Its not finished yet (i.e. expecting more Response objects)
1145 // Or possibly it is a leftover response that we timed the request out previously
1149 // We are going to retract these objects from memory
1157 * This rule responds to SDNC Response Events
1160 rule "SDNC.RESPONSE"
1162 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1163 $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1164 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestID == $event.getRequestId() )
1165 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() )
1166 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1167 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1168 $lock : TargetLock (requestID == $event.getRequestId())
1169 $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() )
1171 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1172 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1173 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1174 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1175 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1177 // Get the result of the operation
1179 PolicyResult policyResult = $operation.onResponse($response);
1180 if (policyResult != null) {
1182 // This Operation has completed, construct a notification showing our results
1184 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1185 notification.setFrom("policy");
1186 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1187 notification.setPolicyScope($params.getPolicyScope());
1188 notification.setPolicyVersion($params.getPolicyVersion());
1189 notification.setMessage($operation.getOperationHistory());
1190 notification.setHistory($operation.getHistory());
1192 // Ensure the operation is complete
1194 if ($operation.isOperationComplete()) {
1196 // It is complete, remove it from memory
1198 retract($operation);
1200 // We must also retract the timer object
1201 // NOTE: We could write a Rule to do this
1205 // Complete the operation
1207 modify($manager) {finishOperation($operation)};
1210 // Just doing this will kick off the LOCKED rule again
1212 modify($operation) {};
1216 // Its not finished yet (i.e. expecting more Response objects)
1218 // Or possibly it is a leftover response that we timed the request out previously
1222 // We are going to retract these objects from memory
1230 * This manages a single timer.
1231 * Due to a bug in the drools code, the drools timer needed to be split from most of the objects in the when clause
1235 timer (expr: $timeout)
1237 $timer : ControlLoopTimer($timeout : delay, !expired)
1239 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1240 logger.info("This is TIMER.FIRED");
1241 modify($timer){setExpired(true)};
1246 * This is the timer that manages the timeout for an individual operation.
1249 rule "EVENT.MANAGER.OPERATION.TIMEOUT"
1251 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1252 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1253 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1254 requestID == $event.getRequestId() )
1255 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1256 onset.getRequestId() == $event.getRequestId() )
1257 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1258 requestID == $event.getRequestId().toString(), timerType == "Operation", expired )
1259 $lock : TargetLock (requestID == $event.getRequestId())
1262 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1263 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1264 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
1265 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1266 $event, $manager, $operation, $lock, $operation, $opTimer);
1269 // Tell it its timed out
1271 $operation.setOperationHasTimedOut();
1273 // Create a notification for it ("DB Write - end operation")
1275 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1276 notification.setFrom("policy");
1277 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1278 notification.setPolicyScope($params.getPolicyScope());
1279 notification.setPolicyVersion($params.getPolicyVersion());
1280 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1281 notification.setMessage($operation.getOperationHistory());
1282 notification.setHistory($operation.getHistory());
1284 // Let interested parties know
1286 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1288 // Get rid of the timer
1292 // Ensure the operation is complete
1294 if ($operation.isOperationComplete() == true) {
1296 // It is complete, remove it from memory
1298 retract($operation);
1300 // Complete the operation
1302 modify($manager) {finishOperation($operation)};
1305 // Just doing this will kick off the LOCKED rule again
1307 modify($operation) {};
1313 * This is the timer that manages the overall control loop timeout.
1316 rule "EVENT.MANAGER.TIMEOUT"
1318 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1319 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1320 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1321 requestID == $event.getRequestId() )
1322 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1323 requestID == $event.getRequestId().toString(), timerType == "ClosedLoop", expired )
1326 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1327 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1329 logger.debug("{}: {}: event={}",
1330 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1333 // Tell the Event Manager it has timed out
1335 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
1336 if (notification != null) {
1337 notification.setFrom("policy");
1338 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1339 notification.setPolicyScope($params.getPolicyScope());
1340 notification.setPolicyVersion($params.getPolicyVersion());
1342 // Let interested parties know
1344 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1347 // Retract the event
1354 * This rule cleans up the manager and other objects after an event has
1358 rule "EVENT.MANAGER.CLEANUP"
1360 $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestID() )
1361 $operations : LinkedList()
1362 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName,
1363 onset.getRequestId() == $requestId ) )
1364 $timers : LinkedList()
1365 from collect( ControlLoopTimer( closedLoopControlName == $clName,
1366 requestID == $requestId.toString() ) )
1367 $locks : LinkedList()
1368 from collect( TargetLock (requestID == $requestId) )
1369 not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) )
1372 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1373 logger.info("{}: {}", $clName, drools.getRule().getName());
1375 logger.debug("{}: {}: manager={} timers={} operations={}",
1376 $clName, drools.getRule().getName(),
1377 $manager, $timers.size(), $operations.size());
1380 // Retract EVERYTHING
1384 for(Object manager: $operations) {
1385 retract((ControlLoopOperationManager) manager);
1387 for(Object timer: $timers) {
1388 retract((ControlLoopTimer) timer);
1390 for(Object lock: $locks) {
1391 TargetLock tgt = (TargetLock) lock;
1393 // Ensure we release the lock
1395 PolicyGuard.unlockTarget(tgt);
1402 * This rule will clean up any rogue onsets where there is no
1403 * ControlLoopParams object corresponding to the onset event.
1406 rule "EVENT.CLEANUP"
1408 $event : VirtualControlLoopEvent( $clName: closedLoopControlName )
1409 not ( ControlLoopParams( getClosedLoopControlName() == $clName) )
1412 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1413 logger.info("{}: {}", $clName, drools.getRule().getName());
1414 logger.debug("{}: {}: orphan onset event={}",
1415 $clName, drools.getRule().getName(), $event);
1422 * This rule responds to SDNR Response Events.
1425 rule "SDNR.RESPONSE"
1427 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1428 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1429 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1430 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1431 requestID == $event.getRequestId() )
1432 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1433 onset.getRequestId() == $event.getRequestId() )
1434 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1435 requestID == $event.getRequestId().toString(), timerType == "Operation", !expired )
1436 $lock : TargetLock (requestID == $event.getRequestId())
1437 $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
1440 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1441 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1442 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1443 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1444 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1447 // Get the result of the operation
1449 PolicyResult policyResult = $operation.onResponse($response);
1450 if (policyResult != null) {
1451 logger.debug("{}: {}: operation finished - result={}",
1452 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1456 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
1458 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1459 notification.setFrom("policy");
1460 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1461 notification.setPolicyScope($params.getPolicyScope());
1462 notification.setPolicyVersion($params.getPolicyVersion());
1463 notification.setMessage($operation.getOperationHistory());
1464 notification.setHistory($operation.getHistory());
1465 if (policyResult.equals(PolicyResult.SUCCESS)) {
1466 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1468 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1470 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1472 // Ensure the operation is complete
1474 if ($operation.isOperationComplete() == true) {
1476 // It is complete, remove it from memory
1478 retract($operation);
1480 // We must also retract the timer object
1481 // NOTE: We could write a Rule to do this
1485 // Complete the operation
1487 modify($manager) {finishOperation($operation)};
1490 // Just doing this will kick off the LOCKED rule again
1492 modify($operation) {};
1496 // Its not finished yet (i.e. expecting more Response objects)
1498 // Or possibly it is a leftover response that we timed the request out previously
1502 // We are going to retract these objects from memory
1509 * Clean Up any lingering SDNR reponses.
1512 rule "SDNR.RESPONSE.CLEANUP"
1514 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1515 $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1516 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1519 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1520 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1521 logger.debug("{}: {}: orphan sdnr response={}",
1522 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);