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.ControlLoopResponse;
30 import org.onap.policy.controlloop.policy.PolicyResult;
31 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
32 import org.onap.policy.controlloop.policy.Policy;
33 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
34 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NewEventStatus;
35 import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager;
36 import org.onap.policy.controlloop.actor.so.SoActorServiceProvider;
37 import org.onap.policy.aai.AaiNqResponseWrapper;
38 import org.onap.policy.appc.Request;
39 import org.onap.policy.appc.Response;
40 import org.onap.policy.appc.CommonHeader;
41 import org.onap.policy.appclcm.LcmRequestWrapper;
42 import org.onap.policy.appclcm.LcmResponseWrapper;
43 import org.onap.policy.appclcm.LcmRequest;
44 import org.onap.policy.appclcm.LcmResponse;
45 import org.onap.policy.appclcm.LcmCommonHeader;
46 import org.onap.policy.sdnr.PciRequestWrapper;
47 import org.onap.policy.sdnr.PciResponseWrapper;
48 import org.onap.policy.sdnr.PciRequest;
49 import org.onap.policy.sdnr.PciResponse;
50 import org.onap.policy.vfc.VfcRequest;
51 import org.onap.policy.vfc.VfcResponse;
52 import org.onap.policy.vfc.VfcManager;
53 import org.onap.policy.so.SoManager;
54 import org.onap.policy.so.SoRequest;
55 import org.onap.policy.so.SoResponseWrapper;
56 import org.onap.policy.sdnc.SdncRequest;
57 import org.onap.policy.sdnc.SdncManager;
58 import org.onap.policy.sdnc.SdncResponse;
59 import org.onap.policy.guard.PolicyGuard;
60 import org.onap.policy.guard.PolicyGuard.LockResult;
61 import org.onap.policy.guard.TargetLock;
62 import org.onap.policy.guard.GuardResult;
63 import org.onap.policy.guard.PolicyGuardRequest;
64 import org.onap.policy.guard.PolicyGuardResponse;
65 import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes;
66 import org.onap.policy.guard.PolicyGuardXacmlHelper;
67 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
69 import org.yaml.snakeyaml.Yaml;
70 import org.yaml.snakeyaml.constructor.Constructor;
72 import org.slf4j.LoggerFactory;
73 import org.slf4j.Logger;
75 import java.time.Instant;
76 import java.util.LinkedList;
77 import java.util.Iterator;
79 import org.onap.policy.drools.system.PolicyEngine;
82 * This object is to provide support for timeouts
83 * due to a bug in drools' built-in timers
85 declare ControlLoopTimer
86 closedLoopControlName : String
90 //timerType is the type of timer: either "ClosedLoop" or "Operation"
96 * Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW.
101 $params : ControlLoopParams()
104 // Note: globals have bad behavior when persistence is used,
105 // hence explicitly getting the logger vs using a global
107 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
108 logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "."
109 + drools.getRule().getName(), $params.getControlLoopYaml());
114 * Called when a Tosca Policy fact is present.
117 rule "NEW TOSCA POLICY"
119 $policy : ToscaPolicy()
122 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
123 logger.info("{}:{}: [{}|{}|{}|{}]: CONTENT: {}", drools.getRule().getName(),
124 $policy.getType(), $policy.getTypeVersion(), $policy.getName(), $policy.getVersion(),
130 * This rule responds to DCAE Events where there is no manager yet. Either it is
131 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
136 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
137 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
138 not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
139 requestId == $event.getRequestId() ) )
142 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
143 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
148 // Check the event, because we need it to not be null when
149 // we create the ControlLoopEventManager. The ControlLoopEventManager
150 // will do extra syntax checking as well check if the closed loop is disabled.
152 if ($event.getRequestId() == null) {
153 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
154 notification.setNotification(ControlLoopNotificationType.REJECTED);
155 notification.setFrom("policy");
156 notification.setMessage("Missing requestId");
157 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
158 notification.setPolicyScope($params.getPolicyScope());
159 notification.setPolicyVersion($params.getPolicyVersion());
162 // Let interested parties know
164 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
167 // Retract it from memory
170 } else if ($event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET) {
171 throw new ControlLoopException($event.getClosedLoopEventStatus() + " received with no prior onset");
174 // Create an EventManager
176 ControlLoopEventManager manager = new ControlLoopEventManager($clName, $event.getRequestId());
178 // Determine if EventManager can actively process the event
179 // (i.e. syntax, is_closed_loop_disabled checks etc.)
181 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
182 notification.setFrom("pdp-0001-controller=controlloop"); // Engine.getInstanceName()
183 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
184 notification.setPolicyScope($params.getPolicyScope());
185 notification.setPolicyVersion($params.getPolicyVersion());
187 // Are we actively pursuing this event?
189 if (notification.getNotification() == ControlLoopNotificationType.ACTIVE) {
191 // Insert Event Manager into memory, this will now kick off processing.
195 // Let interested parties know
197 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
199 // Setup the Overall Control Loop timer
201 ControlLoopTimer clTimer = new ControlLoopTimer();
202 clTimer.setTimerType("ClosedLoop");
203 clTimer.setClosedLoopControlName($event.getClosedLoopControlName());
204 clTimer.setRequestId($event.getRequestId().toString());
205 clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
212 // Let interested parties know
214 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
216 // Retract it from memory
222 // Now that the manager is inserted into Drools working memory, we'll wait for
223 // another rule to fire in order to continue processing. This way we can also
224 // then screen for additional ONSET and ABATED events for this RequestId.
227 } catch (Exception e) {
228 logger.warn("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), e);
230 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
231 notification.setNotification(ControlLoopNotificationType.REJECTED);
232 notification.setMessage("Exception occurred: " + e.getMessage());
233 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
234 notification.setPolicyScope($params.getPolicyScope());
235 notification.setPolicyVersion($params.getPolicyVersion());
239 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
249 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
250 * is now created. We can start processing the yaml specification via the Event Manager.
255 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
256 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
257 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
258 requestId == $event.getRequestId() )
259 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
260 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired )
263 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
264 logger.info("{}: {}: event={} manager={} clTimer={}",
265 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
266 $event, $manager, $clTimer);
270 // Check which event this is.
272 ControlLoopEventManager.NewEventStatus eventStatus = $manager.onNewEvent($event);
274 // Check what kind of event this is
276 if (eventStatus == NewEventStatus.SUBSEQUENT_ONSET) {
278 // We don't care about subsequent onsets
280 logger.info("{}: {}: subsequent onset",
281 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
285 if (eventStatus == NewEventStatus.SYNTAX_ERROR) {
287 // Ignore any bad syntax events
289 logger.warn("{}: {}: syntax error",
290 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
295 // We only want the initial ONSET event in memory,
296 // all the other events need to be retracted to support
297 // cleanup and avoid the other rules being fired for this event.
299 if (eventStatus != NewEventStatus.FIRST_ONSET) {
300 logger.warn("{}: {}: no first onset",
301 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
305 logger.debug("{}: {}: target={}", $clName,
306 $params.getPolicyName() + "." + drools.getRule().getName(), $event.getTarget());
308 // Now start seeing if we need to process this event
312 // Check if this is a Final Event
314 VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
317 if (notification != null) {
319 // Its final, but are we waiting for abatement?
321 if ($manager.getNumAbatements() > 0) {
322 logger.info("{}: {}: abatement received for {}. Closing the control loop",
323 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
324 $event.getRequestId());
325 notification.setFrom("policy");
326 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
327 notification.setPolicyScope($params.getPolicyScope());
328 notification.setPolicyVersion($params.getPolicyVersion());
330 // In this case, we are done
332 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
336 TargetLock lock = $manager.unlockCurrentOperation();
338 logger.debug("{}: {}: retracting lock=", $clName,
339 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
343 // Retract everything from memory
345 logger.info("{}: {}: retracting onset, manager, and timer",
346 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
348 retract($manager.getOnsetEvent());
350 // don't retract manager, etc. - a clean-up rule will do that
353 // TODO - what if we get subsequent Events for this RequestId?
354 // By default, it will all start over again. May be confusing for Ruby.
355 // Or, we could track this and then subsequently ignore the events
359 // Check whether we need to wait for abatement
361 if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) {
362 logger.info("{}: {}: waiting for abatement ..",
363 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
365 logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
366 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
367 $event.getRequestId());
369 notification.setFrom("policy");
370 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
371 notification.setPolicyScope($params.getPolicyScope());
372 notification.setPolicyVersion($params.getPolicyVersion());
375 // In this case, we are done
377 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
381 TargetLock lock = $manager.unlockCurrentOperation();
383 logger.debug("{}: {}: retracting lock=", $clName,
384 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
388 // Retract everything from memory
390 logger.info("{}: {}: retracting onset, manager, and timer",
391 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
393 retract($manager.getOnsetEvent());
395 // don't retract manager, etc. - a clean-up rule will do that
400 // NOT final, so let's ask for the next operation
402 ControlLoopOperationManager operation = $manager.processControlLoop();
403 if (operation != null) {
405 // Let's ask for a lock right away
407 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
408 logger.info("{}: {}: guard lock acquired={}",
409 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
411 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
413 // insert the operation into memory
418 // insert operation timeout object
420 ControlLoopTimer opTimer = new ControlLoopTimer();
421 opTimer.setTimerType("Operation");
422 opTimer.setClosedLoopControlName($event.getClosedLoopControlName());
423 opTimer.setRequestId($event.getRequestId().toString());
424 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
428 // Insert lock into memory
430 insert(result.getB());
433 logger.debug("The target resource {} is already processing",
434 $event.getAai().get($event.getTarget()));
435 notification = new VirtualControlLoopNotification($event);
436 notification.setNotification(ControlLoopNotificationType.REJECTED);
437 notification.setMessage("The target " + $event.getAai().get($event.getTarget())
438 + " is already locked");
439 notification.setFrom("policy");
440 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
441 notification.setPolicyScope($params.getPolicyScope());
442 notification.setPolicyVersion($params.getPolicyVersion());
444 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
448 // don't retract manager, etc. - a clean-up rule will do that
450 if(result.getB() != null) {
451 retract(result.getB());
454 logger.info("{}: {}: starting operation={}",
455 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
459 // Probably waiting for abatement
461 logger.info("{}: {}: no operation, probably waiting for abatement",
462 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
465 } catch (Exception e) {
466 logger.warn("{}: {}: unexpected",
468 $params.getPolicyName() + "." + drools.getRule().getName(), e);
470 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
471 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
472 notification.setMessage(e.getMessage());
473 notification.setFrom("policy");
474 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
475 notification.setPolicyScope($params.getPolicyScope());
476 notification.setPolicyVersion($params.getPolicyVersion());
478 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
482 // don't retract manager, etc. - a clean-up rule will do that
489 * Guard Permitted, let's send request to the actor.
492 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
494 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
495 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
496 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
497 requestId == $event.getRequestId() )
498 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
499 onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
500 $lock : TargetLock (requestId == $event.getRequestId())
501 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
502 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
505 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
506 logger.info("{}: {}: event={} manager={} operation={} lock={}",
507 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
508 $event, $manager, $operation, $lock);
510 Object request = null;
511 boolean caughtException = false;
514 request = $operation.startOperation($event);
516 if (request != null) {
517 logger.debug("{}: {}: starting operation ..",
519 $params.getPolicyName() + "." + drools.getRule().getName());
521 // Tell interested parties we are performing this Operation
523 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
524 notification.setNotification(ControlLoopNotificationType.OPERATION);
525 notification.setMessage($operation.getOperationMessage());
526 notification.setHistory($operation.getHistory());
527 notification.setFrom("policy");
528 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
529 notification.setPolicyScope($params.getPolicyScope());
530 notification.setPolicyVersion($params.getPolicyVersion());
532 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
534 switch ($operation.policy.getActor()){
538 if (request instanceof Request) {
539 PolicyEngine.manager.deliver("APPC-CL", request);
541 else if (request instanceof LcmRequestWrapper) {
542 PolicyEngine.manager.deliver("APPC-LCM-READ", request);
546 // at this point the AAI named query request should have already been made, the response
547 // recieved and used in the construction of the SO Request which is stored in operationRequest
549 if(request instanceof SoRequest) {
550 // Call SO. The response will be inserted into memory once it's received
551 class mySoCallback implements SoManager.SoCallback {
552 public void onSoResponseWrapper(SoResponseWrapper wrapper) {
553 drools.getWorkingMemory().insert(wrapper);
556 SoActorServiceProvider.sendRequest($event.getRequestId().toString(),
559 PolicyEngine.manager.getEnvironmentProperty("so.url"),
560 PolicyEngine.manager.getEnvironmentProperty("so.username"),
561 PolicyEngine.manager.getEnvironmentProperty("so.password"));
565 if (request instanceof VfcRequest) {
566 class myVfcCallback implements VfcManager.VfcCallback {
568 public void onResponse(VfcResponse responseError) {
569 drools.getWorkingMemory().insert(responseError);
573 Thread t = new Thread(new VfcManager(new myVfcCallback(),
575 PolicyEngine.manager.getEnvironmentProperty("vfc.url"),
576 PolicyEngine.manager.getEnvironmentProperty("vfc.username"),
577 PolicyEngine.manager.getEnvironmentProperty("vfc.password")));
582 if (request instanceof PciRequestWrapper) {
583 PolicyEngine.manager.deliver("SDNR-CL", request);
588 if (request instanceof SdncRequest) {
589 class mySdncCallback implements SdncManager.SdncCallback {
590 public void onCallback(SdncResponse response) {
591 drools.getWorkingMemory().insert(response);
595 Thread t = new Thread(new SdncManager(new mySdncCallback(),
596 (SdncRequest)request,
597 PolicyEngine.manager.getEnvironmentProperty("sdnc.url"),
598 PolicyEngine.manager.getEnvironmentProperty("sdnc.username"),
599 PolicyEngine.manager.getEnvironmentProperty("sdnc.password")));
606 // What happens if its null?
608 logger.warn("{}: {}: unexpected null operation request",
610 $params.getPolicyName() + "." + drools.getRule().getName());
611 if ("SO".equals($operation.policy.getActor())) {
614 modify($manager) {finishOperation($operation)};
616 else if ("vfc".equalsIgnoreCase($operation.policy.getActor())) {
619 modify($manager) {finishOperation($operation)};
621 else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) {
624 modify($manager) {finishOperation($operation)};
628 } catch (Exception e) {
629 String msg = e.getMessage();
630 logger.warn("{}: {}: operation={}: AAI failure: {}",
632 $params.getPolicyName() + "." + drools.getRule().getName(),
634 $operation.setOperationHasException(msg);
636 if(request != null) {
638 // Create a notification for it ("DB Write - end operation")
640 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
641 notification.setFrom("policy");
642 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
643 notification.setPolicyScope($params.getPolicyScope());
644 notification.setPolicyVersion($params.getPolicyVersion());
645 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
646 notification.setMessage($operation.getOperationHistory());
647 notification.setHistory($operation.getHistory());
649 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
654 caughtException = true;
657 // Having the modify statement in the catch clause doesn't work for whatever reason
658 if (caughtException) {
659 modify($manager) {finishOperation($operation)};
666 * We were able to acquire a lock so now let's ask Xacml Guard whether
667 * we are allowed to proceed with the request to the actor.
670 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
672 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
673 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
674 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
675 requestId == $event.getRequestId() )
676 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
677 onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" )
678 $lock : TargetLock (requestId == $event.getRequestId())
681 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
682 logger.info("{}: {}: event={} manager={} operation={} lock={}",
683 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
684 $event, $manager, $operation, $lock);
687 // Sending notification that we are about to query Guard ("DB write - start operation")
689 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
690 notification.setNotification(ControlLoopNotificationType.OPERATION);
691 notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " "
692 + $operation.policy.getRecipe());
693 notification.setHistory($operation.getHistory());
694 notification.setFrom("policy");
695 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
696 notification.setPolicyScope($params.getPolicyScope());
697 notification.setPolicyVersion($params.getPolicyVersion());
699 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
702 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
703 // just change guardEnabled to false.
705 // In order to use REST XACML, provide a URL instead of "" as a second argument
706 // to the CallGuardTask() and set the first argument to null
707 // (instead of XacmlPdpEngine).
710 // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
711 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
715 Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
716 drools.getWorkingMemory(),
717 $event.getClosedLoopControlName(),
718 $operation.policy.getActor().toString(),
719 $operation.policy.getRecipe(),
720 $operation.getTargetEntity(),
721 $event.getRequestId().toString(),
723 AaiNqResponseWrapper resp = $manager.getNqVserverFromAai();
724 return(resp == null ? null : resp.countVfModules());
729 insert(new PolicyGuardResponse("Permit", $event.getRequestId(), $operation.policy.getRecipe()));
735 // This rule will be triggered when a thread talking to the XACML Guard inserts a
736 // guardResponse object into the working memory
738 rule "GUARD.RESPONSE"
740 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
741 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
742 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
743 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
744 requestId == $event.getRequestId() )
745 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
746 onset.getRequestId() == $event.getRequestId() )
747 $lock : TargetLock (requestId == $event.getRequestId())
748 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
749 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
750 $guardResponse : PolicyGuardResponse(requestId == $event.getRequestId(), $operation.policy.recipe == operation)
753 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
754 logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
755 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
756 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
759 //we will permit the operation if there was no Guard for it
760 if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){
761 $guardResponse.setResult("Permit");
765 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
767 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
768 notification.setNotification(ControlLoopNotificationType.OPERATION);
769 notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()
770 + " is " + $guardResponse.getResult());
771 notification.setHistory($operation.getHistory());
772 notification.setFrom("policy");
773 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
774 notification.setPolicyScope($params.getPolicyScope());
775 notification.setPolicyVersion($params.getPolicyVersion());
777 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
779 if("Permit".equalsIgnoreCase($guardResponse.getResult())){
781 modify($operation){setGuardApprovalStatus($guardResponse.getResult())};
784 //This is the Deny case
785 $operation.startOperation($event);
786 $operation.setOperationHasGuardDeny();
789 modify($manager) {finishOperation($operation)};
792 retract($guardResponse);
798 * This rule responds to APPC Response Events
800 * I would have like to be consistent and write the Response like this:
801 * $response : Response( CommonHeader.RequestId == $onset.getRequestId() )
803 * However, no compile error was given. But a runtime error was given. I think
804 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
809 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
810 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
811 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
812 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
813 requestId == $event.getRequestId() )
814 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
815 onset.getRequestId() == $event.getRequestId() )
816 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
817 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
818 $lock : TargetLock (requestId == $event.getRequestId())
819 $response : Response( getCommonHeader().RequestId == $event.getRequestId() )
822 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
823 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
824 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
825 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
826 $event, $manager, $operation, $lock, $opTimer, $response);
828 // Get the result of the operation
830 PolicyResult policyResult = $operation.onResponse($response);
831 if (policyResult != null) {
832 logger.debug("{}: {}: operation finished - result={}",
833 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
836 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
838 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
839 notification.setFrom("policy");
840 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
841 notification.setPolicyScope($params.getPolicyScope());
842 notification.setPolicyVersion($params.getPolicyVersion());
843 notification.setMessage($operation.getOperationHistory());
844 notification.setHistory($operation.getHistory());
845 if (policyResult.equals(PolicyResult.SUCCESS)) {
846 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
848 // Let interested parties know
850 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
852 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
854 // Let interested parties know
856 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
859 // Ensure the operation is complete
861 if ($operation.isOperationComplete() == true) {
863 // It is complete, remove it from memory
867 // We must also retract the timer object
868 // NOTE: We could write a Rule to do this
872 // Complete the operation
874 modify($manager) {finishOperation($operation)};
877 // Just doing this will kick off the LOCKED rule again
879 modify($operation) {};
883 // Its not finished yet (i.e. expecting more Response objects)
885 // Or possibly it is a leftover response that we timed the request out previously
889 // We are going to retract these objects from memory
896 * The problem with Responses is that they don't have a controlLoopControlName
897 * field in them, so the only way to attach them is via RequestId. If we have multiple
898 * control loop .drl's loaded in the same container, we need to be sure the cleanup
899 * rules don't remove Responses for other control loops.
902 rule "APPC.RESPONSE.CLEANUP"
904 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
905 $response : Response($id : getCommonHeader().RequestId )
906 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
909 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
910 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
911 logger.debug("{}: {}: orphan appc response={}",
912 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
922 * This rule responds to APPC Response Events using the new LCM interface provided by appc
925 rule "APPC.LCM.RESPONSE"
927 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
928 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
929 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
930 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
931 requestId == $event.getRequestId() )
932 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
933 onset.getRequestId() == $event.getRequestId() )
934 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
935 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
936 $lock : TargetLock (requestId == $event.getRequestId())
937 $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
940 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
941 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
942 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
943 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
944 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
947 // Get the result of the operation
949 PolicyResult policyResult = $operation.onResponse($response);
950 if (policyResult != null) {
951 logger.debug("{}: {}: operation finished - result={}",
952 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
956 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
958 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
959 notification.setFrom("policy");
960 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
961 notification.setPolicyScope($params.getPolicyScope());
962 notification.setPolicyVersion($params.getPolicyVersion());
963 notification.setMessage($operation.getOperationHistory());
964 notification.setHistory($operation.getHistory());
965 if (policyResult.equals(PolicyResult.SUCCESS)) {
966 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
968 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
970 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
972 // Ensure the operation is complete
974 if ($operation.isOperationComplete() == true) {
976 // It is complete, remove it from memory
980 // We must also retract the timer object
981 // NOTE: We could write a Rule to do this
985 // Complete the operation
987 modify($manager) {finishOperation($operation)};
990 // Just doing this will kick off the LOCKED rule again
992 modify($operation) {};
996 // Its not finished yet (i.e. expecting more Response objects)
998 // Or possibly it is a leftover response that we timed the request out previously
1002 // We are going to retract these objects from memory
1009 * Clean Up any lingering LCM reponses
1012 rule "APPC.LCM.RESPONSE.CLEANUP"
1014 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1015 $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1016 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1019 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1020 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1021 logger.debug("{}: {}: orphan appc response={}",
1022 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
1031 * This rule responds to SO Response Events
1036 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1037 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1038 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1039 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1040 requestId == $event.getRequestId() )
1041 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1042 onset.getRequestId() == $event.getRequestId() )
1043 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1044 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1045 $lock : TargetLock (requestId == $event.getRequestId())
1046 $response : SoResponseWrapper(requestId.toString() == $event.getRequestId().toString() )
1049 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1050 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1051 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1052 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1053 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1055 // Get the result of the operation
1057 PolicyResult policyResult = $operation.onResponse($response);
1058 if (policyResult != null) {
1059 logger.debug("{}: {}: operation finished - result={}",
1060 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1064 // This Operation has completed, construct a notification showing our results
1066 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1067 notification.setFrom("policy");
1068 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1069 notification.setPolicyScope($params.getPolicyScope());
1070 notification.setPolicyVersion($params.getPolicyVersion());
1071 notification.setMessage($operation.getOperationHistory());
1072 notification.setHistory($operation.getHistory());
1073 if (policyResult.equals(PolicyResult.SUCCESS)) {
1074 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1076 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1079 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1081 // Ensure the operation is complete
1083 if ($operation.isOperationComplete() == true) {
1085 // It is complete, remove it from memory
1087 retract($operation);
1089 // We must also retract the timer object
1090 // NOTE: We could write a Rule to do this
1094 // Complete the operation
1096 modify($manager) {finishOperation($operation)};
1099 // Just doing this will kick off the LOCKED rule again
1101 modify($operation) {};
1105 // Its not finished yet (i.e. expecting more Response objects)
1107 // Or possibly it is a leftover response that we timed the request out previously
1111 // We are going to retract these objects from memory
1119 * This rule responds to VFC Response Events
1124 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1125 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1126 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1127 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1128 requestId == $event.getRequestId() )
1129 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1130 onset.getRequestId() == $event.getRequestId() )
1131 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1132 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1133 $lock : TargetLock (requestId == $event.getRequestId())
1134 $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() )
1136 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1137 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1138 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1139 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1140 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1142 // Get the result of the operation
1144 PolicyResult policyResult = $operation.onResponse($response);
1145 if (policyResult != null) {
1147 // This Operation has completed, construct a notification showing our results
1149 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1150 notification.setFrom("policy");
1151 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1152 notification.setPolicyScope($params.getPolicyScope());
1153 notification.setPolicyVersion($params.getPolicyVersion());
1154 notification.setMessage($operation.getOperationHistory());
1155 notification.setHistory($operation.getHistory());
1157 // Ensure the operation is complete
1159 if ($operation.isOperationComplete() == true) {
1161 // It is complete, remove it from memory
1163 retract($operation);
1165 // We must also retract the timer object
1166 // NOTE: We could write a Rule to do this
1170 // Complete the operation
1172 modify($manager) {finishOperation($operation)};
1175 // Just doing this will kick off the LOCKED rule again
1177 modify($operation) {};
1181 // Its not finished yet (i.e. expecting more Response objects)
1183 // Or possibly it is a leftover response that we timed the request out previously
1187 // We are going to retract these objects from memory
1195 * This rule responds to SDNC Response Events
1198 rule "SDNC.RESPONSE"
1200 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1201 $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1202 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() )
1203 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() )
1204 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1205 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1206 $lock : TargetLock (requestId == $event.getRequestId())
1207 $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() )
1209 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1210 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1211 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1212 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1213 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1215 // Get the result of the operation
1217 PolicyResult policyResult = $operation.onResponse($response);
1218 if (policyResult != null) {
1220 // This Operation has completed, construct a notification showing our results
1222 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1223 notification.setFrom("policy");
1224 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1225 notification.setPolicyScope($params.getPolicyScope());
1226 notification.setPolicyVersion($params.getPolicyVersion());
1227 notification.setMessage($operation.getOperationHistory());
1228 notification.setHistory($operation.getHistory());
1230 // Ensure the operation is complete
1232 if ($operation.isOperationComplete()) {
1234 // It is complete, remove it from memory
1236 retract($operation);
1238 // We must also retract the timer object
1239 // NOTE: We could write a Rule to do this
1243 // Complete the operation
1245 modify($manager) {finishOperation($operation)};
1248 // Just doing this will kick off the LOCKED rule again
1250 modify($operation) {};
1254 // Its not finished yet (i.e. expecting more Response objects)
1256 // Or possibly it is a leftover response that we timed the request out previously
1260 // We are going to retract these objects from memory
1268 * This manages a single timer.
1269 * Due to a bug in the drools code, the drools timer needed to be split from most of the objects in the when clause
1273 timer (expr: $timeout)
1275 $timer : ControlLoopTimer($timeout : delay, !expired)
1277 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1278 logger.info("This is TIMER.FIRED");
1279 modify($timer){setExpired(true)};
1284 * This is the timer that manages the timeout for an individual operation.
1287 rule "EVENT.MANAGER.OPERATION.TIMEOUT"
1289 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1290 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1291 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1292 requestId == $event.getRequestId() )
1293 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1294 onset.getRequestId() == $event.getRequestId() )
1295 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1296 requestId == $event.getRequestId().toString(), timerType == "Operation", expired )
1297 $lock : TargetLock (requestId == $event.getRequestId())
1300 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1301 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1302 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
1303 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1304 $event, $manager, $operation, $lock, $operation, $opTimer);
1307 // Tell it its timed out
1309 $operation.setOperationHasTimedOut();
1311 // Create a notification for it ("DB Write - end operation")
1313 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1314 notification.setFrom("policy");
1315 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1316 notification.setPolicyScope($params.getPolicyScope());
1317 notification.setPolicyVersion($params.getPolicyVersion());
1318 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1319 notification.setMessage($operation.getOperationHistory());
1320 notification.setHistory($operation.getHistory());
1322 // Let interested parties know
1324 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1326 // Get rid of the timer
1330 // Ensure the operation is complete
1332 if ($operation.isOperationComplete() == true) {
1334 // It is complete, remove it from memory
1336 retract($operation);
1338 // Complete the operation
1340 modify($manager) {finishOperation($operation)};
1343 // Just doing this will kick off the LOCKED rule again
1345 modify($operation) {};
1351 * This is the timer that manages the overall control loop timeout.
1354 rule "EVENT.MANAGER.TIMEOUT"
1356 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1357 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1358 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1359 requestId == $event.getRequestId() )
1360 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1361 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", expired )
1364 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1365 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1367 logger.debug("{}: {}: event={}",
1368 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1371 // Tell the Event Manager it has timed out
1373 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
1374 if (notification != null) {
1375 notification.setFrom("policy");
1376 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1377 notification.setPolicyScope($params.getPolicyScope());
1378 notification.setPolicyVersion($params.getPolicyVersion());
1380 // Let interested parties know
1382 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1385 // Retract the event
1392 * This rule cleans up the manager and other objects after an event has
1396 rule "EVENT.MANAGER.CLEANUP"
1398 $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestId() )
1399 $operations : LinkedList()
1400 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName,
1401 onset.getRequestId() == $requestId ) )
1402 $timers : LinkedList()
1403 from collect( ControlLoopTimer( closedLoopControlName == $clName,
1404 requestId == $requestId.toString() ) )
1405 $locks : LinkedList()
1406 from collect( TargetLock (requestId == $requestId) )
1407 not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) )
1410 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1411 logger.info("{}: {}", $clName, drools.getRule().getName());
1413 logger.debug("{}: {}: manager={} timers={} operations={}",
1414 $clName, drools.getRule().getName(),
1415 $manager, $timers.size(), $operations.size());
1418 // Retract EVERYTHING
1422 for(Object manager: $operations) {
1423 retract((ControlLoopOperationManager) manager);
1425 for(Object timer: $timers) {
1426 retract((ControlLoopTimer) timer);
1428 for(Object lock: $locks) {
1429 TargetLock tgt = (TargetLock) lock;
1431 // Ensure we release the lock
1433 PolicyGuard.unlockTarget(tgt);
1440 * This rule will clean up any rogue onsets where there is no
1441 * ControlLoopParams object corresponding to the onset event.
1444 rule "EVENT.CLEANUP"
1446 $event : VirtualControlLoopEvent( $clName: closedLoopControlName )
1447 not ( ControlLoopParams( getClosedLoopControlName() == $clName) )
1450 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1451 logger.info("{}: {}", $clName, drools.getRule().getName());
1452 logger.debug("{}: {}: orphan onset event={}",
1453 $clName, drools.getRule().getName(), $event);
1460 * This rule responds to SDNR Response Events.
1463 rule "SDNR.RESPONSE"
1465 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1466 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1467 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1468 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1469 requestId == $event.getRequestId() )
1470 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1471 onset.getRequestId() == $event.getRequestId() )
1472 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1473 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1474 $lock : TargetLock (requestId == $event.getRequestId())
1475 $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
1478 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1479 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1480 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1481 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1482 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1485 // Get the result of the operation
1487 PolicyResult policyResult = $operation.onResponse($response);
1488 if (policyResult != null) {
1489 logger.debug("{}: {}: operation finished - result={}",
1490 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1494 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
1496 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1497 notification.setFrom("policy");
1498 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1499 notification.setPolicyScope($params.getPolicyScope());
1500 notification.setPolicyVersion($params.getPolicyVersion());
1501 notification.setMessage($operation.getOperationHistory());
1502 notification.setHistory($operation.getHistory());
1503 if (policyResult.equals(PolicyResult.SUCCESS)) {
1504 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1506 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1508 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1510 ControlLoopResponse clResponse = $operation.getControlLoopResponse($response, $event);
1511 PolicyEngine.manager.deliver("DCAE_CL_RSP", clResponse);
1513 // Ensure the operation is complete
1515 if ($operation.isOperationComplete() == true) {
1517 // It is complete, remove it from memory
1519 retract($operation);
1521 // We must also retract the timer object
1522 // NOTE: We could write a Rule to do this
1526 // Complete the operation
1528 modify($manager) {finishOperation($operation)};
1531 // Just doing this will kick off the LOCKED rule again
1533 modify($operation) {};
1537 // Its not finished yet (i.e. expecting more Response objects)
1539 // Or possibly it is a leftover response that we timed the request out previously
1543 // We are going to retract these objects from memory
1550 * Clean Up any lingering SDNR reponses.
1553 rule "SDNR.RESPONSE.CLEANUP"
1555 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1556 $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1557 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1560 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1561 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1562 logger.debug("{}: {}: orphan sdnr response={}",
1563 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);