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.NewEventStatus;
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.SoResponseWrapper;
55 import org.onap.policy.sdnc.SdncRequest;
56 import org.onap.policy.sdnc.SdncManager;
57 import org.onap.policy.sdnc.SdncResponse;
58 import org.onap.policy.guard.PolicyGuard;
59 import org.onap.policy.guard.PolicyGuard.LockResult;
60 import org.onap.policy.guard.TargetLock;
61 import org.onap.policy.guard.GuardResult;
62 import org.onap.policy.guard.PolicyGuardRequest;
63 import org.onap.policy.guard.PolicyGuardResponse;
64 import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes;
65 import org.onap.policy.guard.PolicyGuardXacmlHelper;
67 import org.yaml.snakeyaml.Yaml;
68 import org.yaml.snakeyaml.constructor.Constructor;
70 import org.slf4j.LoggerFactory;
71 import org.slf4j.Logger;
73 import java.time.Instant;
74 import java.util.LinkedList;
75 import java.util.Iterator;
77 import org.onap.policy.drools.system.PolicyEngine;
80 * This object is to provide support for timeouts
81 * due to a bug in drools' built-in timers
83 declare ControlLoopTimer
84 closedLoopControlName : String
88 //timerType is the type of timer: either "ClosedLoop" or "Operation"
94 * Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW.
99 $params : ControlLoopParams()
102 // Note: globals have bad behavior when persistence is used,
103 // hence explicitly getting the logger vs using a global
105 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
106 logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "."
107 + drools.getRule().getName(), $params.getControlLoopYaml());
112 * This rule responds to DCAE Events where there is no manager yet. Either it is
113 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
118 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
119 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
120 not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
121 requestId == $event.getRequestId() ) )
124 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
125 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
130 // Check the event, because we need it to not be null when
131 // we create the ControlLoopEventManager. The ControlLoopEventManager
132 // will do extra syntax checking as well check if the closed loop is disabled.
134 if ($event.getRequestId() == null) {
135 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
136 notification.setNotification(ControlLoopNotificationType.REJECTED);
137 notification.setFrom("policy");
138 notification.setMessage("Missing requestId");
139 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
140 notification.setPolicyScope($params.getPolicyScope());
141 notification.setPolicyVersion($params.getPolicyVersion());
144 // Let interested parties know
146 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
149 // Retract it from memory
152 } else if ($event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET) {
153 throw new ControlLoopException($event.getClosedLoopEventStatus() + " received with no prior onset");
156 // Create an EventManager
158 ControlLoopEventManager manager = new ControlLoopEventManager($clName, $event.getRequestId());
160 // Determine if EventManager can actively process the event
161 // (i.e. syntax, is_closed_loop_disabled checks etc.)
163 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
164 notification.setFrom("pdp-0001-controller=controlloop"); // Engine.getInstanceName()
165 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
166 notification.setPolicyScope($params.getPolicyScope());
167 notification.setPolicyVersion($params.getPolicyVersion());
169 // Are we actively pursuing this event?
171 if (notification.getNotification() == ControlLoopNotificationType.ACTIVE) {
173 // Insert Event Manager into memory, this will now kick off processing.
177 // Let interested parties know
179 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
181 // Setup the Overall Control Loop timer
183 ControlLoopTimer clTimer = new ControlLoopTimer();
184 clTimer.setTimerType("ClosedLoop");
185 clTimer.setClosedLoopControlName($event.getClosedLoopControlName());
186 clTimer.setRequestId($event.getRequestId().toString());
187 clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
194 // Let interested parties know
196 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
198 // Retract it from memory
204 // Now that the manager is inserted into Drools working memory, we'll wait for
205 // another rule to fire in order to continue processing. This way we can also
206 // then screen for additional ONSET and ABATED events for this RequestId.
209 } catch (Exception e) {
210 logger.warn("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), e);
212 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
213 notification.setNotification(ControlLoopNotificationType.REJECTED);
214 notification.setMessage("Exception occurred: " + e.getMessage());
215 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
216 notification.setPolicyScope($params.getPolicyScope());
217 notification.setPolicyVersion($params.getPolicyVersion());
221 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
231 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
232 * is now created. We can start processing the yaml specification via the Event Manager.
237 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
238 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
239 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
240 requestId == $event.getRequestId() )
241 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
242 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired )
245 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
246 logger.info("{}: {}: event={} manager={} clTimer={}",
247 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
248 $event, $manager, $clTimer);
252 // Check which event this is.
254 ControlLoopEventManager.NewEventStatus eventStatus = $manager.onNewEvent($event);
256 // Check what kind of event this is
258 if (eventStatus == NewEventStatus.SUBSEQUENT_ONSET) {
260 // We don't care about subsequent onsets
262 logger.info("{}: {}: subsequent onset",
263 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
267 if (eventStatus == NewEventStatus.SYNTAX_ERROR) {
269 // Ignore any bad syntax events
271 logger.warn("{}: {}: syntax error",
272 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
277 // We only want the initial ONSET event in memory,
278 // all the other events need to be retracted to support
279 // cleanup and avoid the other rules being fired for this event.
281 if (eventStatus != NewEventStatus.FIRST_ONSET) {
282 logger.warn("{}: {}: no first onset",
283 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
287 logger.debug("{}: {}: target={}", $clName,
288 $params.getPolicyName() + "." + drools.getRule().getName(), $event.getTarget());
290 // Now start seeing if we need to process this event
294 // Check if this is a Final Event
296 VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
299 if (notification != null) {
301 // Its final, but are we waiting for abatement?
303 if ($manager.getNumAbatements() > 0) {
304 logger.info("{}: {}: abatement received for {}. Closing the control loop",
305 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
306 $event.getRequestId());
307 notification.setFrom("policy");
308 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
309 notification.setPolicyScope($params.getPolicyScope());
310 notification.setPolicyVersion($params.getPolicyVersion());
312 // In this case, we are done
314 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
318 TargetLock lock = $manager.unlockCurrentOperation();
320 logger.debug("{}: {}: retracting lock=", $clName,
321 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
325 // Retract everything from memory
327 logger.info("{}: {}: retracting onset, manager, and timer",
328 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
330 retract($manager.getOnsetEvent());
332 // don't retract manager, etc. - a clean-up rule will do that
335 // TODO - what if we get subsequent Events for this RequestId?
336 // By default, it will all start over again. May be confusing for Ruby.
337 // Or, we could track this and then subsequently ignore the events
341 // Check whether we need to wait for abatement
343 if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) {
344 logger.info("{}: {}: waiting for abatement ..",
345 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
347 logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
348 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
349 $event.getRequestId());
351 notification.setFrom("policy");
352 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
353 notification.setPolicyScope($params.getPolicyScope());
354 notification.setPolicyVersion($params.getPolicyVersion());
357 // In this case, we are done
359 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
363 TargetLock lock = $manager.unlockCurrentOperation();
365 logger.debug("{}: {}: retracting lock=", $clName,
366 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
370 // Retract everything from memory
372 logger.info("{}: {}: retracting onset, manager, and timer",
373 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
375 retract($manager.getOnsetEvent());
377 // don't retract manager, etc. - a clean-up rule will do that
382 // NOT final, so let's ask for the next operation
384 ControlLoopOperationManager operation = $manager.processControlLoop();
385 if (operation != null) {
387 // Let's ask for a lock right away
389 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
390 logger.info("{}: {}: guard lock acquired={}",
391 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
393 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
395 // insert the operation into memory
400 // insert operation timeout object
402 ControlLoopTimer opTimer = new ControlLoopTimer();
403 opTimer.setTimerType("Operation");
404 opTimer.setClosedLoopControlName($event.getClosedLoopControlName());
405 opTimer.setRequestId($event.getRequestId().toString());
406 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
410 // Insert lock into memory
412 insert(result.getB());
415 logger.debug("The target resource {} is already processing",
416 $event.getAai().get($event.getTarget()));
417 notification = new VirtualControlLoopNotification($event);
418 notification.setNotification(ControlLoopNotificationType.REJECTED);
419 notification.setMessage("The target " + $event.getAai().get($event.getTarget())
420 + " is already locked");
421 notification.setFrom("policy");
422 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
423 notification.setPolicyScope($params.getPolicyScope());
424 notification.setPolicyVersion($params.getPolicyVersion());
426 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
430 // don't retract manager, etc. - a clean-up rule will do that
432 if(result.getB() != null) {
433 retract(result.getB());
436 logger.info("{}: {}: starting operation={}",
437 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
441 // Probably waiting for abatement
443 logger.info("{}: {}: no operation, probably waiting for abatement",
444 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
447 } catch (Exception e) {
448 logger.warn("{}: {}: unexpected",
450 $params.getPolicyName() + "." + drools.getRule().getName(), e);
452 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
453 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
454 notification.setMessage(e.getMessage());
455 notification.setFrom("policy");
456 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
457 notification.setPolicyScope($params.getPolicyScope());
458 notification.setPolicyVersion($params.getPolicyVersion());
460 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
464 // don't retract manager, etc. - a clean-up rule will do that
471 * Guard Permitted, let's send request to the actor.
474 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
476 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
477 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
478 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
479 requestId == $event.getRequestId() )
480 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
481 onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
482 $lock : TargetLock (requestId == $event.getRequestId())
483 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
484 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
487 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
488 logger.info("{}: {}: event={} manager={} operation={} lock={}",
489 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
490 $event, $manager, $operation, $lock);
492 Object request = null;
493 boolean caughtException = false;
496 request = $operation.startOperation($event);
498 if (request != null) {
499 logger.debug("{}: {}: starting operation ..",
501 $params.getPolicyName() + "." + drools.getRule().getName());
503 // Tell interested parties we are performing this Operation
505 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
506 notification.setNotification(ControlLoopNotificationType.OPERATION);
507 notification.setMessage($operation.getOperationMessage());
508 notification.setHistory($operation.getHistory());
509 notification.setFrom("policy");
510 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
511 notification.setPolicyScope($params.getPolicyScope());
512 notification.setPolicyVersion($params.getPolicyVersion());
514 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
516 switch ($operation.policy.getActor()){
520 if (request instanceof Request) {
521 PolicyEngine.manager.deliver("APPC-CL", request);
523 else if (request instanceof LcmRequestWrapper) {
524 PolicyEngine.manager.deliver("APPC-LCM-READ", request);
528 // at this point the AAI named query request should have already been made, the response
529 // recieved and used in the construction of the SO Request which is stored in operationRequest
531 if(request instanceof SoRequest) {
532 // Call SO. The response will be inserted into memory once it's received
533 class mySoCallback implements SoManager.SoCallback {
534 public void onSoResponseWrapper(SoResponseWrapper wrapper) {
535 drools.getWorkingMemory().insert(wrapper);
538 SoActorServiceProvider.sendRequest($event.getRequestId().toString(),
541 PolicyEngine.manager.getEnvironmentProperty("so.url"),
542 PolicyEngine.manager.getEnvironmentProperty("so.username"),
543 PolicyEngine.manager.getEnvironmentProperty("so.password"));
547 if (request instanceof VfcRequest) {
548 class myVfcCallback implements VfcManager.VfcCallback {
550 public void onResponse(VfcResponse responseError) {
551 drools.getWorkingMemory().insert(responseError);
555 Thread t = new Thread(new VfcManager(new myVfcCallback(),
557 PolicyEngine.manager.getEnvironmentProperty("vfc.url"),
558 PolicyEngine.manager.getEnvironmentProperty("vfc.username"),
559 PolicyEngine.manager.getEnvironmentProperty("vfc.password")));
564 if (request instanceof PciRequestWrapper) {
565 PolicyEngine.manager.deliver("SDNR-CL", request);
570 if (request instanceof SdncRequest) {
571 class mySdncCallback implements SdncManager.SdncCallback {
572 public void onCallback(SdncResponse response) {
573 drools.getWorkingMemory().insert(response);
577 Thread t = new Thread(new SdncManager(new mySdncCallback(),
578 (SdncRequest)request,
579 PolicyEngine.manager.getEnvironmentProperty("sdnc.url"),
580 PolicyEngine.manager.getEnvironmentProperty("sdnc.username"),
581 PolicyEngine.manager.getEnvironmentProperty("sdnc.password")));
588 // What happens if its null?
590 logger.warn("{}: {}: unexpected null operation request",
592 $params.getPolicyName() + "." + drools.getRule().getName());
593 if ("SO".equals($operation.policy.getActor())) {
596 modify($manager) {finishOperation($operation)};
598 else if ("vfc".equalsIgnoreCase($operation.policy.getActor())) {
601 modify($manager) {finishOperation($operation)};
603 else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) {
606 modify($manager) {finishOperation($operation)};
610 } catch (Exception e) {
611 String msg = e.getMessage();
612 logger.warn("{}: {}: operation={}: AAI failure: {}",
614 $params.getPolicyName() + "." + drools.getRule().getName(),
616 $operation.setOperationHasException(msg);
618 if(request != null) {
620 // Create a notification for it ("DB Write - end operation")
622 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
623 notification.setFrom("policy");
624 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
625 notification.setPolicyScope($params.getPolicyScope());
626 notification.setPolicyVersion($params.getPolicyVersion());
627 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
628 notification.setMessage($operation.getOperationHistory());
629 notification.setHistory($operation.getHistory());
631 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
636 caughtException = true;
639 // Having the modify statement in the catch clause doesn't work for whatever reason
640 if (caughtException) {
641 modify($manager) {finishOperation($operation)};
648 * We were able to acquire a lock so now let's ask Xacml Guard whether
649 * we are allowed to proceed with the request to the actor.
652 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
654 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
655 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
656 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
657 requestId == $event.getRequestId() )
658 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
659 onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" )
660 $lock : TargetLock (requestId == $event.getRequestId())
663 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
664 logger.info("{}: {}: event={} manager={} operation={} lock={}",
665 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
666 $event, $manager, $operation, $lock);
669 // Sending notification that we are about to query Guard ("DB write - start operation")
671 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
672 notification.setNotification(ControlLoopNotificationType.OPERATION);
673 notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " "
674 + $operation.policy.getRecipe());
675 notification.setHistory($operation.getHistory());
676 notification.setFrom("policy");
677 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
678 notification.setPolicyScope($params.getPolicyScope());
679 notification.setPolicyVersion($params.getPolicyVersion());
681 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
684 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
685 // just change guardEnabled to false.
687 // In order to use REST XACML, provide a URL instead of "" as a second argument
688 // to the CallGuardTask() and set the first argument to null
689 // (instead of XacmlPdpEngine).
692 // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
693 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
697 Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
698 drools.getWorkingMemory(),
699 $event.getClosedLoopControlName(),
700 $operation.policy.getActor().toString(),
701 $operation.policy.getRecipe(),
702 $operation.getTargetEntity(),
703 $event.getRequestId().toString(),
705 AaiNqResponseWrapper resp = $manager.getNqVserverFromAai();
706 return(resp == null ? null : resp.countVfModules());
711 insert(new PolicyGuardResponse("Permit", $event.getRequestId(), $operation.policy.getRecipe()));
717 // This rule will be triggered when a thread talking to the XACML Guard inserts a
718 // guardResponse object into the working memory
720 rule "GUARD.RESPONSE"
722 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
723 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
724 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
725 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
726 requestId == $event.getRequestId() )
727 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
728 onset.getRequestId() == $event.getRequestId() )
729 $lock : TargetLock (requestId == $event.getRequestId())
730 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
731 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
732 $guardResponse : PolicyGuardResponse(requestId == $event.getRequestId(), $operation.policy.recipe == operation)
735 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
736 logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
737 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
738 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
741 //we will permit the operation if there was no Guard for it
742 if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){
743 $guardResponse.setResult("Permit");
747 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
749 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
750 notification.setNotification(ControlLoopNotificationType.OPERATION);
751 notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()
752 + " is " + $guardResponse.getResult());
753 notification.setHistory($operation.getHistory());
754 notification.setFrom("policy");
755 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
756 notification.setPolicyScope($params.getPolicyScope());
757 notification.setPolicyVersion($params.getPolicyVersion());
759 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
761 if("Permit".equalsIgnoreCase($guardResponse.getResult())){
763 modify($operation){setGuardApprovalStatus($guardResponse.getResult())};
766 //This is the Deny case
767 $operation.startOperation($event);
768 $operation.setOperationHasGuardDeny();
771 modify($manager) {finishOperation($operation)};
774 retract($guardResponse);
780 * This rule responds to APPC Response Events
782 * I would have like to be consistent and write the Response like this:
783 * $response : Response( CommonHeader.RequestId == $onset.getRequestId() )
785 * However, no compile error was given. But a runtime error was given. I think
786 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
791 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
792 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
793 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
794 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
795 requestId == $event.getRequestId() )
796 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
797 onset.getRequestId() == $event.getRequestId() )
798 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
799 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
800 $lock : TargetLock (requestId == $event.getRequestId())
801 $response : Response( getCommonHeader().RequestId == $event.getRequestId() )
804 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
805 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
806 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
807 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
808 $event, $manager, $operation, $lock, $opTimer, $response);
810 // Get the result of the operation
812 PolicyResult policyResult = $operation.onResponse($response);
813 if (policyResult != null) {
814 logger.debug("{}: {}: operation finished - result={}",
815 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
818 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
820 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
821 notification.setFrom("policy");
822 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
823 notification.setPolicyScope($params.getPolicyScope());
824 notification.setPolicyVersion($params.getPolicyVersion());
825 notification.setMessage($operation.getOperationHistory());
826 notification.setHistory($operation.getHistory());
827 if (policyResult.equals(PolicyResult.SUCCESS)) {
828 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
830 // Let interested parties know
832 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
834 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
836 // Let interested parties know
838 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
841 // Ensure the operation is complete
843 if ($operation.isOperationComplete() == true) {
845 // It is complete, remove it from memory
849 // We must also retract the timer object
850 // NOTE: We could write a Rule to do this
854 // Complete the operation
856 modify($manager) {finishOperation($operation)};
859 // Just doing this will kick off the LOCKED rule again
861 modify($operation) {};
865 // Its not finished yet (i.e. expecting more Response objects)
867 // Or possibly it is a leftover response that we timed the request out previously
871 // We are going to retract these objects from memory
878 * The problem with Responses is that they don't have a controlLoopControlName
879 * field in them, so the only way to attach them is via RequestId. If we have multiple
880 * control loop .drl's loaded in the same container, we need to be sure the cleanup
881 * rules don't remove Responses for other control loops.
884 rule "APPC.RESPONSE.CLEANUP"
886 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
887 $response : Response($id : getCommonHeader().RequestId )
888 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
891 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
892 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
893 logger.debug("{}: {}: orphan appc response={}",
894 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
904 * This rule responds to APPC Response Events using the new LCM interface provided by appc
907 rule "APPC.LCM.RESPONSE"
909 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
910 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
911 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
912 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
913 requestId == $event.getRequestId() )
914 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
915 onset.getRequestId() == $event.getRequestId() )
916 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
917 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
918 $lock : TargetLock (requestId == $event.getRequestId())
919 $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
922 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
923 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
924 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
925 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
926 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
929 // Get the result of the operation
931 PolicyResult policyResult = $operation.onResponse($response);
932 if (policyResult != null) {
933 logger.debug("{}: {}: operation finished - result={}",
934 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
938 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
940 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
941 notification.setFrom("policy");
942 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
943 notification.setPolicyScope($params.getPolicyScope());
944 notification.setPolicyVersion($params.getPolicyVersion());
945 notification.setMessage($operation.getOperationHistory());
946 notification.setHistory($operation.getHistory());
947 if (policyResult.equals(PolicyResult.SUCCESS)) {
948 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
950 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
952 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
954 // Ensure the operation is complete
956 if ($operation.isOperationComplete() == true) {
958 // It is complete, remove it from memory
962 // We must also retract the timer object
963 // NOTE: We could write a Rule to do this
967 // Complete the operation
969 modify($manager) {finishOperation($operation)};
972 // Just doing this will kick off the LOCKED rule again
974 modify($operation) {};
978 // Its not finished yet (i.e. expecting more Response objects)
980 // Or possibly it is a leftover response that we timed the request out previously
984 // We are going to retract these objects from memory
991 * Clean Up any lingering LCM reponses
994 rule "APPC.LCM.RESPONSE.CLEANUP"
996 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
997 $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId )
998 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1001 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1002 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1003 logger.debug("{}: {}: orphan appc response={}",
1004 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
1013 * This rule responds to SO Response Events
1018 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1019 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1020 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1021 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1022 requestId == $event.getRequestId() )
1023 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1024 onset.getRequestId() == $event.getRequestId() )
1025 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1026 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1027 $lock : TargetLock (requestId == $event.getRequestId())
1028 $response : SoResponseWrapper(requestId.toString() == $event.getRequestId().toString() )
1031 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1032 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1033 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1034 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1035 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1037 // Get the result of the operation
1039 PolicyResult policyResult = $operation.onResponse($response);
1040 if (policyResult != null) {
1041 logger.debug("{}: {}: operation finished - result={}",
1042 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1046 // This Operation has completed, construct a notification showing our results
1048 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1049 notification.setFrom("policy");
1050 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1051 notification.setPolicyScope($params.getPolicyScope());
1052 notification.setPolicyVersion($params.getPolicyVersion());
1053 notification.setMessage($operation.getOperationHistory());
1054 notification.setHistory($operation.getHistory());
1055 if (policyResult.equals(PolicyResult.SUCCESS)) {
1056 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1058 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1061 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1063 // Ensure the operation is complete
1065 if ($operation.isOperationComplete() == true) {
1067 // It is complete, remove it from memory
1069 retract($operation);
1071 // We must also retract the timer object
1072 // NOTE: We could write a Rule to do this
1076 // Complete the operation
1078 modify($manager) {finishOperation($operation)};
1081 // Just doing this will kick off the LOCKED rule again
1083 modify($operation) {};
1087 // Its not finished yet (i.e. expecting more Response objects)
1089 // Or possibly it is a leftover response that we timed the request out previously
1093 // We are going to retract these objects from memory
1101 * This rule responds to VFC Response Events
1106 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1107 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1108 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1109 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1110 requestId == $event.getRequestId() )
1111 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1112 onset.getRequestId() == $event.getRequestId() )
1113 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1114 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1115 $lock : TargetLock (requestId == $event.getRequestId())
1116 $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() )
1118 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1119 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1120 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1121 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1122 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1124 // Get the result of the operation
1126 PolicyResult policyResult = $operation.onResponse($response);
1127 if (policyResult != null) {
1129 // This Operation has completed, construct a notification showing our results
1131 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1132 notification.setFrom("policy");
1133 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1134 notification.setPolicyScope($params.getPolicyScope());
1135 notification.setPolicyVersion($params.getPolicyVersion());
1136 notification.setMessage($operation.getOperationHistory());
1137 notification.setHistory($operation.getHistory());
1139 // Ensure the operation is complete
1141 if ($operation.isOperationComplete() == true) {
1143 // It is complete, remove it from memory
1145 retract($operation);
1147 // We must also retract the timer object
1148 // NOTE: We could write a Rule to do this
1152 // Complete the operation
1154 modify($manager) {finishOperation($operation)};
1157 // Just doing this will kick off the LOCKED rule again
1159 modify($operation) {};
1163 // Its not finished yet (i.e. expecting more Response objects)
1165 // Or possibly it is a leftover response that we timed the request out previously
1169 // We are going to retract these objects from memory
1177 * This rule responds to SDNC Response Events
1180 rule "SDNC.RESPONSE"
1182 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1183 $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1184 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() )
1185 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() )
1186 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1187 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1188 $lock : TargetLock (requestId == $event.getRequestId())
1189 $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() )
1191 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1192 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1193 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1194 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1195 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1197 // Get the result of the operation
1199 PolicyResult policyResult = $operation.onResponse($response);
1200 if (policyResult != null) {
1202 // This Operation has completed, construct a notification showing our results
1204 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1205 notification.setFrom("policy");
1206 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1207 notification.setPolicyScope($params.getPolicyScope());
1208 notification.setPolicyVersion($params.getPolicyVersion());
1209 notification.setMessage($operation.getOperationHistory());
1210 notification.setHistory($operation.getHistory());
1212 // Ensure the operation is complete
1214 if ($operation.isOperationComplete()) {
1216 // It is complete, remove it from memory
1218 retract($operation);
1220 // We must also retract the timer object
1221 // NOTE: We could write a Rule to do this
1225 // Complete the operation
1227 modify($manager) {finishOperation($operation)};
1230 // Just doing this will kick off the LOCKED rule again
1232 modify($operation) {};
1236 // Its not finished yet (i.e. expecting more Response objects)
1238 // Or possibly it is a leftover response that we timed the request out previously
1242 // We are going to retract these objects from memory
1250 * This manages a single timer.
1251 * Due to a bug in the drools code, the drools timer needed to be split from most of the objects in the when clause
1255 timer (expr: $timeout)
1257 $timer : ControlLoopTimer($timeout : delay, !expired)
1259 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1260 logger.info("This is TIMER.FIRED");
1261 modify($timer){setExpired(true)};
1266 * This is the timer that manages the timeout for an individual operation.
1269 rule "EVENT.MANAGER.OPERATION.TIMEOUT"
1271 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1272 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1273 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1274 requestId == $event.getRequestId() )
1275 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1276 onset.getRequestId() == $event.getRequestId() )
1277 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1278 requestId == $event.getRequestId().toString(), timerType == "Operation", expired )
1279 $lock : TargetLock (requestId == $event.getRequestId())
1282 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1283 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1284 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
1285 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1286 $event, $manager, $operation, $lock, $operation, $opTimer);
1289 // Tell it its timed out
1291 $operation.setOperationHasTimedOut();
1293 // Create a notification for it ("DB Write - end operation")
1295 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1296 notification.setFrom("policy");
1297 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1298 notification.setPolicyScope($params.getPolicyScope());
1299 notification.setPolicyVersion($params.getPolicyVersion());
1300 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1301 notification.setMessage($operation.getOperationHistory());
1302 notification.setHistory($operation.getHistory());
1304 // Let interested parties know
1306 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1308 // Get rid of the timer
1312 // Ensure the operation is complete
1314 if ($operation.isOperationComplete() == true) {
1316 // It is complete, remove it from memory
1318 retract($operation);
1320 // Complete the operation
1322 modify($manager) {finishOperation($operation)};
1325 // Just doing this will kick off the LOCKED rule again
1327 modify($operation) {};
1333 * This is the timer that manages the overall control loop timeout.
1336 rule "EVENT.MANAGER.TIMEOUT"
1338 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1339 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1340 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1341 requestId == $event.getRequestId() )
1342 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1343 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", expired )
1346 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1347 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1349 logger.debug("{}: {}: event={}",
1350 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1353 // Tell the Event Manager it has timed out
1355 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
1356 if (notification != null) {
1357 notification.setFrom("policy");
1358 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1359 notification.setPolicyScope($params.getPolicyScope());
1360 notification.setPolicyVersion($params.getPolicyVersion());
1362 // Let interested parties know
1364 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1367 // Retract the event
1374 * This rule cleans up the manager and other objects after an event has
1378 rule "EVENT.MANAGER.CLEANUP"
1380 $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestId() )
1381 $operations : LinkedList()
1382 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName,
1383 onset.getRequestId() == $requestId ) )
1384 $timers : LinkedList()
1385 from collect( ControlLoopTimer( closedLoopControlName == $clName,
1386 requestId == $requestId.toString() ) )
1387 $locks : LinkedList()
1388 from collect( TargetLock (requestId == $requestId) )
1389 not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) )
1392 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1393 logger.info("{}: {}", $clName, drools.getRule().getName());
1395 logger.debug("{}: {}: manager={} timers={} operations={}",
1396 $clName, drools.getRule().getName(),
1397 $manager, $timers.size(), $operations.size());
1400 // Retract EVERYTHING
1404 for(Object manager: $operations) {
1405 retract((ControlLoopOperationManager) manager);
1407 for(Object timer: $timers) {
1408 retract((ControlLoopTimer) timer);
1410 for(Object lock: $locks) {
1411 TargetLock tgt = (TargetLock) lock;
1413 // Ensure we release the lock
1415 PolicyGuard.unlockTarget(tgt);
1422 * This rule will clean up any rogue onsets where there is no
1423 * ControlLoopParams object corresponding to the onset event.
1426 rule "EVENT.CLEANUP"
1428 $event : VirtualControlLoopEvent( $clName: closedLoopControlName )
1429 not ( ControlLoopParams( getClosedLoopControlName() == $clName) )
1432 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1433 logger.info("{}: {}", $clName, drools.getRule().getName());
1434 logger.debug("{}: {}: orphan onset event={}",
1435 $clName, drools.getRule().getName(), $event);
1442 * This rule responds to SDNR Response Events.
1445 rule "SDNR.RESPONSE"
1447 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1448 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1449 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1450 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1451 requestId == $event.getRequestId() )
1452 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1453 onset.getRequestId() == $event.getRequestId() )
1454 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1455 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1456 $lock : TargetLock (requestId == $event.getRequestId())
1457 $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
1460 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1461 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1462 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1463 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1464 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1467 // Get the result of the operation
1469 PolicyResult policyResult = $operation.onResponse($response);
1470 if (policyResult != null) {
1471 logger.debug("{}: {}: operation finished - result={}",
1472 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1476 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
1478 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1479 notification.setFrom("policy");
1480 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1481 notification.setPolicyScope($params.getPolicyScope());
1482 notification.setPolicyVersion($params.getPolicyVersion());
1483 notification.setMessage($operation.getOperationHistory());
1484 notification.setHistory($operation.getHistory());
1485 if (policyResult.equals(PolicyResult.SUCCESS)) {
1486 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1488 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1490 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1492 // Ensure the operation is complete
1494 if ($operation.isOperationComplete() == true) {
1496 // It is complete, remove it from memory
1498 retract($operation);
1500 // We must also retract the timer object
1501 // NOTE: We could write a Rule to do this
1505 // Complete the operation
1507 modify($manager) {finishOperation($operation)};
1510 // Just doing this will kick off the LOCKED rule again
1512 modify($operation) {};
1516 // Its not finished yet (i.e. expecting more Response objects)
1518 // Or possibly it is a leftover response that we timed the request out previously
1522 // We are going to retract these objects from memory
1529 * Clean Up any lingering SDNR reponses.
1532 rule "SDNR.RESPONSE.CLEANUP"
1534 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1535 $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1536 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1539 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1540 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1541 logger.debug("{}: {}: orphan sdnr response={}",
1542 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);