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;
68 import org.yaml.snakeyaml.Yaml;
69 import org.yaml.snakeyaml.constructor.Constructor;
71 import org.slf4j.LoggerFactory;
72 import org.slf4j.Logger;
74 import java.time.Instant;
75 import java.util.LinkedList;
76 import java.util.Iterator;
78 import org.onap.policy.drools.system.PolicyEngine;
81 * This object is to provide support for timeouts
82 * due to a bug in drools' built-in timers
84 declare ControlLoopTimer
85 closedLoopControlName : String
89 //timerType is the type of timer: either "ClosedLoop" or "Operation"
95 * Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW.
100 $params : ControlLoopParams()
103 // Note: globals have bad behavior when persistence is used,
104 // hence explicitly getting the logger vs using a global
106 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
107 logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "."
108 + drools.getRule().getName(), $params.getControlLoopYaml());
113 * This rule responds to DCAE Events where there is no manager yet. Either it is
114 * the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
119 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
120 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
121 not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
122 requestId == $event.getRequestId() ) )
125 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
126 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
131 // Check the event, because we need it to not be null when
132 // we create the ControlLoopEventManager. The ControlLoopEventManager
133 // will do extra syntax checking as well check if the closed loop is disabled.
135 if ($event.getRequestId() == null) {
136 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
137 notification.setNotification(ControlLoopNotificationType.REJECTED);
138 notification.setFrom("policy");
139 notification.setMessage("Missing requestId");
140 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
141 notification.setPolicyScope($params.getPolicyScope());
142 notification.setPolicyVersion($params.getPolicyVersion());
145 // Let interested parties know
147 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
150 // Retract it from memory
153 } else if ($event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET) {
154 throw new ControlLoopException($event.getClosedLoopEventStatus() + " received with no prior onset");
157 // Create an EventManager
159 ControlLoopEventManager manager = new ControlLoopEventManager($clName, $event.getRequestId());
161 // Determine if EventManager can actively process the event
162 // (i.e. syntax, is_closed_loop_disabled checks etc.)
164 VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
165 notification.setFrom("pdp-0001-controller=controlloop"); // Engine.getInstanceName()
166 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
167 notification.setPolicyScope($params.getPolicyScope());
168 notification.setPolicyVersion($params.getPolicyVersion());
170 // Are we actively pursuing this event?
172 if (notification.getNotification() == ControlLoopNotificationType.ACTIVE) {
174 // Insert Event Manager into memory, this will now kick off processing.
178 // Let interested parties know
180 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
182 // Setup the Overall Control Loop timer
184 ControlLoopTimer clTimer = new ControlLoopTimer();
185 clTimer.setTimerType("ClosedLoop");
186 clTimer.setClosedLoopControlName($event.getClosedLoopControlName());
187 clTimer.setRequestId($event.getRequestId().toString());
188 clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
195 // Let interested parties know
197 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
199 // Retract it from memory
205 // Now that the manager is inserted into Drools working memory, we'll wait for
206 // another rule to fire in order to continue processing. This way we can also
207 // then screen for additional ONSET and ABATED events for this RequestId.
210 } catch (Exception e) {
211 logger.warn("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), e);
213 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
214 notification.setNotification(ControlLoopNotificationType.REJECTED);
215 notification.setMessage("Exception occurred: " + e.getMessage());
216 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
217 notification.setPolicyScope($params.getPolicyScope());
218 notification.setPolicyVersion($params.getPolicyVersion());
222 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
232 * This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
233 * is now created. We can start processing the yaml specification via the Event Manager.
238 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
239 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
240 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
241 requestId == $event.getRequestId() )
242 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
243 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired )
246 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
247 logger.info("{}: {}: event={} manager={} clTimer={}",
248 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
249 $event, $manager, $clTimer);
253 // Check which event this is.
255 ControlLoopEventManager.NewEventStatus eventStatus = $manager.onNewEvent($event);
257 // Check what kind of event this is
259 if (eventStatus == NewEventStatus.SUBSEQUENT_ONSET) {
261 // We don't care about subsequent onsets
263 logger.info("{}: {}: subsequent onset",
264 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
268 if (eventStatus == NewEventStatus.SYNTAX_ERROR) {
270 // Ignore any bad syntax events
272 logger.warn("{}: {}: syntax error",
273 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
278 // We only want the initial ONSET event in memory,
279 // all the other events need to be retracted to support
280 // cleanup and avoid the other rules being fired for this event.
282 if (eventStatus != NewEventStatus.FIRST_ONSET) {
283 logger.warn("{}: {}: no first onset",
284 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
288 logger.debug("{}: {}: target={}", $clName,
289 $params.getPolicyName() + "." + drools.getRule().getName(), $event.getTarget());
291 // Now start seeing if we need to process this event
295 // Check if this is a Final Event
297 VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
300 if (notification != null) {
302 // Its final, but are we waiting for abatement?
304 if ($manager.getNumAbatements() > 0) {
305 logger.info("{}: {}: abatement received for {}. Closing the control loop",
306 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
307 $event.getRequestId());
308 notification.setFrom("policy");
309 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
310 notification.setPolicyScope($params.getPolicyScope());
311 notification.setPolicyVersion($params.getPolicyVersion());
313 // In this case, we are done
315 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
319 TargetLock lock = $manager.unlockCurrentOperation();
321 logger.debug("{}: {}: retracting lock=", $clName,
322 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
326 // Retract everything from memory
328 logger.info("{}: {}: retracting onset, manager, and timer",
329 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
331 retract($manager.getOnsetEvent());
333 // don't retract manager, etc. - a clean-up rule will do that
336 // TODO - what if we get subsequent Events for this RequestId?
337 // By default, it will all start over again. May be confusing for Ruby.
338 // Or, we could track this and then subsequently ignore the events
342 // Check whether we need to wait for abatement
344 if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) {
345 logger.info("{}: {}: waiting for abatement ..",
346 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
348 logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
349 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
350 $event.getRequestId());
352 notification.setFrom("policy");
353 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
354 notification.setPolicyScope($params.getPolicyScope());
355 notification.setPolicyVersion($params.getPolicyVersion());
358 // In this case, we are done
360 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
364 TargetLock lock = $manager.unlockCurrentOperation();
366 logger.debug("{}: {}: retracting lock=", $clName,
367 $params.getPolicyName() + "." + drools.getRule().getName(), lock);
371 // Retract everything from memory
373 logger.info("{}: {}: retracting onset, manager, and timer",
374 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
376 retract($manager.getOnsetEvent());
378 // don't retract manager, etc. - a clean-up rule will do that
383 // NOT final, so let's ask for the next operation
385 ControlLoopOperationManager operation = $manager.processControlLoop();
386 if (operation != null) {
388 // Let's ask for a lock right away
390 LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
391 logger.info("{}: {}: guard lock acquired={}",
392 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
394 if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
396 // insert the operation into memory
401 // insert operation timeout object
403 ControlLoopTimer opTimer = new ControlLoopTimer();
404 opTimer.setTimerType("Operation");
405 opTimer.setClosedLoopControlName($event.getClosedLoopControlName());
406 opTimer.setRequestId($event.getRequestId().toString());
407 opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
411 // Insert lock into memory
413 insert(result.getB());
416 logger.debug("The target resource {} is already processing",
417 $event.getAai().get($event.getTarget()));
418 notification = new VirtualControlLoopNotification($event);
419 notification.setNotification(ControlLoopNotificationType.REJECTED);
420 notification.setMessage("The target " + $event.getAai().get($event.getTarget())
421 + " is already locked");
422 notification.setFrom("policy");
423 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
424 notification.setPolicyScope($params.getPolicyScope());
425 notification.setPolicyVersion($params.getPolicyVersion());
427 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
431 // don't retract manager, etc. - a clean-up rule will do that
433 if(result.getB() != null) {
434 retract(result.getB());
437 logger.info("{}: {}: starting operation={}",
438 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
442 // Probably waiting for abatement
444 logger.info("{}: {}: no operation, probably waiting for abatement",
445 $clName, $params.getPolicyName() + "." + drools.getRule().getName());
448 } catch (Exception e) {
449 logger.warn("{}: {}: unexpected",
451 $params.getPolicyName() + "." + drools.getRule().getName(), e);
453 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
454 notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
455 notification.setMessage(e.getMessage());
456 notification.setFrom("policy");
457 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
458 notification.setPolicyScope($params.getPolicyScope());
459 notification.setPolicyVersion($params.getPolicyVersion());
461 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
465 // don't retract manager, etc. - a clean-up rule will do that
472 * Guard Permitted, let's send request to the actor.
475 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
477 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
478 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
479 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
480 requestId == $event.getRequestId() )
481 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
482 onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) )
483 $lock : TargetLock (requestId == $event.getRequestId())
484 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
485 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
488 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
489 logger.info("{}: {}: event={} manager={} operation={} lock={}",
490 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
491 $event, $manager, $operation, $lock);
493 Object request = null;
494 boolean caughtException = false;
497 request = $operation.startOperation($event);
499 if (request != null) {
500 logger.debug("{}: {}: starting operation ..",
502 $params.getPolicyName() + "." + drools.getRule().getName());
504 // Tell interested parties we are performing this Operation
506 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
507 notification.setNotification(ControlLoopNotificationType.OPERATION);
508 notification.setMessage($operation.getOperationMessage());
509 notification.setHistory($operation.getHistory());
510 notification.setFrom("policy");
511 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
512 notification.setPolicyScope($params.getPolicyScope());
513 notification.setPolicyVersion($params.getPolicyVersion());
515 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
517 switch ($operation.policy.getActor()){
521 if (request instanceof Request) {
522 PolicyEngine.manager.deliver("APPC-CL", request);
524 else if (request instanceof LcmRequestWrapper) {
525 PolicyEngine.manager.deliver("APPC-LCM-READ", request);
529 // at this point the AAI named query request should have already been made, the response
530 // recieved and used in the construction of the SO Request which is stored in operationRequest
532 if(request instanceof SoRequest) {
533 // Call SO. The response will be inserted into memory once it's received
534 class mySoCallback implements SoManager.SoCallback {
535 public void onSoResponseWrapper(SoResponseWrapper wrapper) {
536 drools.getWorkingMemory().insert(wrapper);
539 SoActorServiceProvider.sendRequest($event.getRequestId().toString(),
542 PolicyEngine.manager.getEnvironmentProperty("so.url"),
543 PolicyEngine.manager.getEnvironmentProperty("so.username"),
544 PolicyEngine.manager.getEnvironmentProperty("so.password"));
548 if (request instanceof VfcRequest) {
549 class myVfcCallback implements VfcManager.VfcCallback {
551 public void onResponse(VfcResponse responseError) {
552 drools.getWorkingMemory().insert(responseError);
556 Thread t = new Thread(new VfcManager(new myVfcCallback(),
558 PolicyEngine.manager.getEnvironmentProperty("vfc.url"),
559 PolicyEngine.manager.getEnvironmentProperty("vfc.username"),
560 PolicyEngine.manager.getEnvironmentProperty("vfc.password")));
565 if (request instanceof PciRequestWrapper) {
566 PolicyEngine.manager.deliver("SDNR-CL", request);
571 if (request instanceof SdncRequest) {
572 class mySdncCallback implements SdncManager.SdncCallback {
573 public void onCallback(SdncResponse response) {
574 drools.getWorkingMemory().insert(response);
578 Thread t = new Thread(new SdncManager(new mySdncCallback(),
579 (SdncRequest)request,
580 PolicyEngine.manager.getEnvironmentProperty("sdnc.url"),
581 PolicyEngine.manager.getEnvironmentProperty("sdnc.username"),
582 PolicyEngine.manager.getEnvironmentProperty("sdnc.password")));
589 // What happens if its null?
591 logger.warn("{}: {}: unexpected null operation request",
593 $params.getPolicyName() + "." + drools.getRule().getName());
594 if ("SO".equals($operation.policy.getActor())) {
597 modify($manager) {finishOperation($operation)};
599 else if ("vfc".equalsIgnoreCase($operation.policy.getActor())) {
602 modify($manager) {finishOperation($operation)};
604 else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) {
607 modify($manager) {finishOperation($operation)};
611 } catch (Exception e) {
612 String msg = e.getMessage();
613 logger.warn("{}: {}: operation={}: AAI failure: {}",
615 $params.getPolicyName() + "." + drools.getRule().getName(),
617 $operation.setOperationHasException(msg);
619 if(request != null) {
621 // Create a notification for it ("DB Write - end operation")
623 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
624 notification.setFrom("policy");
625 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
626 notification.setPolicyScope($params.getPolicyScope());
627 notification.setPolicyVersion($params.getPolicyVersion());
628 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
629 notification.setMessage($operation.getOperationHistory());
630 notification.setHistory($operation.getHistory());
632 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
637 caughtException = true;
640 // Having the modify statement in the catch clause doesn't work for whatever reason
641 if (caughtException) {
642 modify($manager) {finishOperation($operation)};
649 * We were able to acquire a lock so now let's ask Xacml Guard whether
650 * we are allowed to proceed with the request to the actor.
653 rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
655 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
656 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
657 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
658 requestId == $event.getRequestId() )
659 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
660 onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" )
661 $lock : TargetLock (requestId == $event.getRequestId())
664 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
665 logger.info("{}: {}: event={} manager={} operation={} lock={}",
666 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
667 $event, $manager, $operation, $lock);
670 // Sending notification that we are about to query Guard ("DB write - start operation")
672 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
673 notification.setNotification(ControlLoopNotificationType.OPERATION);
674 notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " "
675 + $operation.policy.getRecipe());
676 notification.setHistory($operation.getHistory());
677 notification.setFrom("policy");
678 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
679 notification.setPolicyScope($params.getPolicyScope());
680 notification.setPolicyVersion($params.getPolicyVersion());
682 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
685 // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
686 // just change guardEnabled to false.
688 // In order to use REST XACML, provide a URL instead of "" as a second argument
689 // to the CallGuardTask() and set the first argument to null
690 // (instead of XacmlPdpEngine).
693 // NOTE: The environment properties uses "guard.disabled" but the boolean is guardEnabled
694 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
698 Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
699 drools.getWorkingMemory(),
700 $event.getClosedLoopControlName(),
701 $operation.policy.getActor().toString(),
702 $operation.policy.getRecipe(),
703 $operation.getTargetEntity(),
704 $event.getRequestId().toString(),
706 AaiNqResponseWrapper resp = $manager.getNqVserverFromAai();
707 return(resp == null ? null : resp.countVfModules());
712 insert(new PolicyGuardResponse("Permit", $event.getRequestId(), $operation.policy.getRecipe()));
718 // This rule will be triggered when a thread talking to the XACML Guard inserts a
719 // guardResponse object into the working memory
721 rule "GUARD.RESPONSE"
723 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
724 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
725 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
726 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
727 requestId == $event.getRequestId() )
728 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
729 onset.getRequestId() == $event.getRequestId() )
730 $lock : TargetLock (requestId == $event.getRequestId())
731 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
732 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
733 $guardResponse : PolicyGuardResponse(requestId == $event.getRequestId(), $operation.policy.recipe == operation)
736 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
737 logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
738 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
739 $event, $manager, $operation, $lock, $opTimer, $guardResponse);
742 //we will permit the operation if there was no Guard for it
743 if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){
744 $guardResponse.setResult("Permit");
748 // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
750 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
751 notification.setNotification(ControlLoopNotificationType.OPERATION);
752 notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()
753 + " is " + $guardResponse.getResult());
754 notification.setHistory($operation.getHistory());
755 notification.setFrom("policy");
756 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
757 notification.setPolicyScope($params.getPolicyScope());
758 notification.setPolicyVersion($params.getPolicyVersion());
760 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
762 if("Permit".equalsIgnoreCase($guardResponse.getResult())){
764 modify($operation){setGuardApprovalStatus($guardResponse.getResult())};
767 //This is the Deny case
768 $operation.startOperation($event);
769 $operation.setOperationHasGuardDeny();
772 modify($manager) {finishOperation($operation)};
775 retract($guardResponse);
781 * This rule responds to APPC Response Events
783 * I would have like to be consistent and write the Response like this:
784 * $response : Response( CommonHeader.RequestId == $onset.getRequestId() )
786 * However, no compile error was given. But a runtime error was given. I think
787 * because drools is confused between the classname CommonHeader vs the property CommonHeader.
792 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
793 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
794 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
795 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
796 requestId == $event.getRequestId() )
797 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
798 onset.getRequestId() == $event.getRequestId() )
799 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
800 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
801 $lock : TargetLock (requestId == $event.getRequestId())
802 $response : Response( getCommonHeader().RequestId == $event.getRequestId() )
805 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
806 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
807 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
808 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
809 $event, $manager, $operation, $lock, $opTimer, $response);
811 // Get the result of the operation
813 PolicyResult policyResult = $operation.onResponse($response);
814 if (policyResult != null) {
815 logger.debug("{}: {}: operation finished - result={}",
816 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
819 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
821 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
822 notification.setFrom("policy");
823 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
824 notification.setPolicyScope($params.getPolicyScope());
825 notification.setPolicyVersion($params.getPolicyVersion());
826 notification.setMessage($operation.getOperationHistory());
827 notification.setHistory($operation.getHistory());
828 if (policyResult.equals(PolicyResult.SUCCESS)) {
829 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
831 // Let interested parties know
833 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
835 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
837 // Let interested parties know
839 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
842 // Ensure the operation is complete
844 if ($operation.isOperationComplete() == true) {
846 // It is complete, remove it from memory
850 // We must also retract the timer object
851 // NOTE: We could write a Rule to do this
855 // Complete the operation
857 modify($manager) {finishOperation($operation)};
860 // Just doing this will kick off the LOCKED rule again
862 modify($operation) {};
866 // Its not finished yet (i.e. expecting more Response objects)
868 // Or possibly it is a leftover response that we timed the request out previously
872 // We are going to retract these objects from memory
879 * The problem with Responses is that they don't have a controlLoopControlName
880 * field in them, so the only way to attach them is via RequestId. If we have multiple
881 * control loop .drl's loaded in the same container, we need to be sure the cleanup
882 * rules don't remove Responses for other control loops.
885 rule "APPC.RESPONSE.CLEANUP"
887 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
888 $response : Response($id : getCommonHeader().RequestId )
889 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
892 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
893 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
894 logger.debug("{}: {}: orphan appc response={}",
895 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
905 * This rule responds to APPC Response Events using the new LCM interface provided by appc
908 rule "APPC.LCM.RESPONSE"
910 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
911 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
912 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
913 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
914 requestId == $event.getRequestId() )
915 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
916 onset.getRequestId() == $event.getRequestId() )
917 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
918 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
919 $lock : TargetLock (requestId == $event.getRequestId())
920 $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
923 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
924 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
925 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
926 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
927 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
930 // Get the result of the operation
932 PolicyResult policyResult = $operation.onResponse($response);
933 if (policyResult != null) {
934 logger.debug("{}: {}: operation finished - result={}",
935 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
939 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
941 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
942 notification.setFrom("policy");
943 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
944 notification.setPolicyScope($params.getPolicyScope());
945 notification.setPolicyVersion($params.getPolicyVersion());
946 notification.setMessage($operation.getOperationHistory());
947 notification.setHistory($operation.getHistory());
948 if (policyResult.equals(PolicyResult.SUCCESS)) {
949 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
951 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
953 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
955 // Ensure the operation is complete
957 if ($operation.isOperationComplete() == true) {
959 // It is complete, remove it from memory
963 // We must also retract the timer object
964 // NOTE: We could write a Rule to do this
968 // Complete the operation
970 modify($manager) {finishOperation($operation)};
973 // Just doing this will kick off the LOCKED rule again
975 modify($operation) {};
979 // Its not finished yet (i.e. expecting more Response objects)
981 // Or possibly it is a leftover response that we timed the request out previously
985 // We are going to retract these objects from memory
992 * Clean Up any lingering LCM reponses
995 rule "APPC.LCM.RESPONSE.CLEANUP"
997 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
998 $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId )
999 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1002 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1003 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1004 logger.debug("{}: {}: orphan appc response={}",
1005 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);
1014 * This rule responds to SO Response Events
1019 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1020 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1021 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1022 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1023 requestId == $event.getRequestId() )
1024 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1025 onset.getRequestId() == $event.getRequestId() )
1026 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1027 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1028 $lock : TargetLock (requestId == $event.getRequestId())
1029 $response : SoResponseWrapper(requestId.toString() == $event.getRequestId().toString() )
1032 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1033 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1034 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1035 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1036 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1038 // Get the result of the operation
1040 PolicyResult policyResult = $operation.onResponse($response);
1041 if (policyResult != null) {
1042 logger.debug("{}: {}: operation finished - result={}",
1043 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1047 // This Operation has completed, construct a notification showing our results
1049 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1050 notification.setFrom("policy");
1051 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1052 notification.setPolicyScope($params.getPolicyScope());
1053 notification.setPolicyVersion($params.getPolicyVersion());
1054 notification.setMessage($operation.getOperationHistory());
1055 notification.setHistory($operation.getHistory());
1056 if (policyResult.equals(PolicyResult.SUCCESS)) {
1057 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1059 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1062 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1064 // Ensure the operation is complete
1066 if ($operation.isOperationComplete() == true) {
1068 // It is complete, remove it from memory
1070 retract($operation);
1072 // We must also retract the timer object
1073 // NOTE: We could write a Rule to do this
1077 // Complete the operation
1079 modify($manager) {finishOperation($operation)};
1082 // Just doing this will kick off the LOCKED rule again
1084 modify($operation) {};
1088 // Its not finished yet (i.e. expecting more Response objects)
1090 // Or possibly it is a leftover response that we timed the request out previously
1094 // We are going to retract these objects from memory
1102 * This rule responds to VFC Response Events
1107 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1108 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1109 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1110 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1111 requestId == $event.getRequestId() )
1112 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1113 onset.getRequestId() == $event.getRequestId() )
1114 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1115 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1116 $lock : TargetLock (requestId == $event.getRequestId())
1117 $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() )
1119 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1120 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1121 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1122 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1123 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1125 // Get the result of the operation
1127 PolicyResult policyResult = $operation.onResponse($response);
1128 if (policyResult != null) {
1130 // This Operation has completed, construct a notification showing our results
1132 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1133 notification.setFrom("policy");
1134 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1135 notification.setPolicyScope($params.getPolicyScope());
1136 notification.setPolicyVersion($params.getPolicyVersion());
1137 notification.setMessage($operation.getOperationHistory());
1138 notification.setHistory($operation.getHistory());
1140 // Ensure the operation is complete
1142 if ($operation.isOperationComplete() == true) {
1144 // It is complete, remove it from memory
1146 retract($operation);
1148 // We must also retract the timer object
1149 // NOTE: We could write a Rule to do this
1153 // Complete the operation
1155 modify($manager) {finishOperation($operation)};
1158 // Just doing this will kick off the LOCKED rule again
1160 modify($operation) {};
1164 // Its not finished yet (i.e. expecting more Response objects)
1166 // Or possibly it is a leftover response that we timed the request out previously
1170 // We are going to retract these objects from memory
1178 * This rule responds to SDNC Response Events
1181 rule "SDNC.RESPONSE"
1183 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1184 $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1185 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() )
1186 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() )
1187 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1188 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1189 $lock : TargetLock (requestId == $event.getRequestId())
1190 $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() )
1192 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1193 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1194 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1195 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1196 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1198 // Get the result of the operation
1200 PolicyResult policyResult = $operation.onResponse($response);
1201 if (policyResult != null) {
1203 // This Operation has completed, construct a notification showing our results
1205 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1206 notification.setFrom("policy");
1207 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1208 notification.setPolicyScope($params.getPolicyScope());
1209 notification.setPolicyVersion($params.getPolicyVersion());
1210 notification.setMessage($operation.getOperationHistory());
1211 notification.setHistory($operation.getHistory());
1213 // Ensure the operation is complete
1215 if ($operation.isOperationComplete()) {
1217 // It is complete, remove it from memory
1219 retract($operation);
1221 // We must also retract the timer object
1222 // NOTE: We could write a Rule to do this
1226 // Complete the operation
1228 modify($manager) {finishOperation($operation)};
1231 // Just doing this will kick off the LOCKED rule again
1233 modify($operation) {};
1237 // Its not finished yet (i.e. expecting more Response objects)
1239 // Or possibly it is a leftover response that we timed the request out previously
1243 // We are going to retract these objects from memory
1251 * This manages a single timer.
1252 * Due to a bug in the drools code, the drools timer needed to be split from most of the objects in the when clause
1256 timer (expr: $timeout)
1258 $timer : ControlLoopTimer($timeout : delay, !expired)
1260 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1261 logger.info("This is TIMER.FIRED");
1262 modify($timer){setExpired(true)};
1267 * This is the timer that manages the timeout for an individual operation.
1270 rule "EVENT.MANAGER.OPERATION.TIMEOUT"
1272 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1273 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1274 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1275 requestId == $event.getRequestId() )
1276 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1277 onset.getRequestId() == $event.getRequestId() )
1278 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1279 requestId == $event.getRequestId().toString(), timerType == "Operation", expired )
1280 $lock : TargetLock (requestId == $event.getRequestId())
1283 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1284 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1285 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
1286 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1287 $event, $manager, $operation, $lock, $operation, $opTimer);
1290 // Tell it its timed out
1292 $operation.setOperationHasTimedOut();
1294 // Create a notification for it ("DB Write - end operation")
1296 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1297 notification.setFrom("policy");
1298 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1299 notification.setPolicyScope($params.getPolicyScope());
1300 notification.setPolicyVersion($params.getPolicyVersion());
1301 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1302 notification.setMessage($operation.getOperationHistory());
1303 notification.setHistory($operation.getHistory());
1305 // Let interested parties know
1307 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1309 // Get rid of the timer
1313 // Ensure the operation is complete
1315 if ($operation.isOperationComplete() == true) {
1317 // It is complete, remove it from memory
1319 retract($operation);
1321 // Complete the operation
1323 modify($manager) {finishOperation($operation)};
1326 // Just doing this will kick off the LOCKED rule again
1328 modify($operation) {};
1334 * This is the timer that manages the overall control loop timeout.
1337 rule "EVENT.MANAGER.TIMEOUT"
1339 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1340 $event : VirtualControlLoopEvent( closedLoopControlName == $clName )
1341 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1342 requestId == $event.getRequestId() )
1343 $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1344 requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", expired )
1347 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1348 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1350 logger.debug("{}: {}: event={}",
1351 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1354 // Tell the Event Manager it has timed out
1356 VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
1357 if (notification != null) {
1358 notification.setFrom("policy");
1359 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1360 notification.setPolicyScope($params.getPolicyScope());
1361 notification.setPolicyVersion($params.getPolicyVersion());
1363 // Let interested parties know
1365 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1368 // Retract the event
1375 * This rule cleans up the manager and other objects after an event has
1379 rule "EVENT.MANAGER.CLEANUP"
1381 $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestId() )
1382 $operations : LinkedList()
1383 from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName,
1384 onset.getRequestId() == $requestId ) )
1385 $timers : LinkedList()
1386 from collect( ControlLoopTimer( closedLoopControlName == $clName,
1387 requestId == $requestId.toString() ) )
1388 $locks : LinkedList()
1389 from collect( TargetLock (requestId == $requestId) )
1390 not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) )
1393 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1394 logger.info("{}: {}", $clName, drools.getRule().getName());
1396 logger.debug("{}: {}: manager={} timers={} operations={}",
1397 $clName, drools.getRule().getName(),
1398 $manager, $timers.size(), $operations.size());
1401 // Retract EVERYTHING
1405 for(Object manager: $operations) {
1406 retract((ControlLoopOperationManager) manager);
1408 for(Object timer: $timers) {
1409 retract((ControlLoopTimer) timer);
1411 for(Object lock: $locks) {
1412 TargetLock tgt = (TargetLock) lock;
1414 // Ensure we release the lock
1416 PolicyGuard.unlockTarget(tgt);
1423 * This rule will clean up any rogue onsets where there is no
1424 * ControlLoopParams object corresponding to the onset event.
1427 rule "EVENT.CLEANUP"
1429 $event : VirtualControlLoopEvent( $clName: closedLoopControlName )
1430 not ( ControlLoopParams( getClosedLoopControlName() == $clName) )
1433 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1434 logger.info("{}: {}", $clName, drools.getRule().getName());
1435 logger.debug("{}: {}: orphan onset event={}",
1436 $clName, drools.getRule().getName(), $event);
1443 * This rule responds to SDNR Response Events.
1446 rule "SDNR.RESPONSE"
1448 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1449 $event : VirtualControlLoopEvent( closedLoopControlName == $clName,
1450 closedLoopEventStatus == ControlLoopEventStatus.ONSET )
1451 $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(),
1452 requestId == $event.getRequestId() )
1453 $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(),
1454 onset.getRequestId() == $event.getRequestId() )
1455 $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(),
1456 requestId == $event.getRequestId().toString(), timerType == "Operation", !expired )
1457 $lock : TargetLock (requestId == $event.getRequestId())
1458 $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() )
1461 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1462 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1463 logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
1464 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1465 $event, $manager, $operation, $lock, $operation, $opTimer, $response);
1468 // Get the result of the operation
1470 PolicyResult policyResult = $operation.onResponse($response);
1471 if (policyResult != null) {
1472 logger.debug("{}: {}: operation finished - result={}",
1473 $clName, $params.getPolicyName() + "." + drools.getRule().getName(),
1477 // This Operation has completed, construct a notification showing our results. (DB write - end operation)
1479 VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
1480 notification.setFrom("policy");
1481 notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName());
1482 notification.setPolicyScope($params.getPolicyScope());
1483 notification.setPolicyVersion($params.getPolicyVersion());
1484 notification.setMessage($operation.getOperationHistory());
1485 notification.setHistory($operation.getHistory());
1486 if (policyResult.equals(PolicyResult.SUCCESS)) {
1487 notification.setNotification(ControlLoopNotificationType.OPERATION_SUCCESS);
1489 notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE);
1491 PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
1493 ControlLoopResponse clResponse = $operation.getControlLoopResponse($response, $event);
1494 PolicyEngine.manager.deliver("DCAE_CL_RSP", clResponse);
1496 // Ensure the operation is complete
1498 if ($operation.isOperationComplete() == true) {
1500 // It is complete, remove it from memory
1502 retract($operation);
1504 // We must also retract the timer object
1505 // NOTE: We could write a Rule to do this
1509 // Complete the operation
1511 modify($manager) {finishOperation($operation)};
1514 // Just doing this will kick off the LOCKED rule again
1516 modify($operation) {};
1520 // Its not finished yet (i.e. expecting more Response objects)
1522 // Or possibly it is a leftover response that we timed the request out previously
1526 // We are going to retract these objects from memory
1533 * Clean Up any lingering SDNR reponses.
1536 rule "SDNR.RESPONSE.CLEANUP"
1538 $params : ControlLoopParams( $clName : getClosedLoopControlName() )
1539 $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId )
1540 not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
1543 Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
1544 logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName());
1545 logger.debug("{}: {}: orphan sdnr response={}",
1546 $clName, $params.getPolicyName() + "." + drools.getRule().getName(), $id);