From ac5c19ddbed1ff5905d16a6359ee23b4888c717a Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 27 Sep 2019 11:22:47 -0400 Subject: Modify drools-applications to use new Lock API Modified code to use new Lock API. Also deleted TargetLock and PolicyGuard, as they are no longer needed. Issue-ID: POLICY-2113 Signed-off-by: Jim Hahn Change-Id: I5bc9b7732f9cfc6056789b2902d9f6f838b560be --- .../src/main/resources/usecases.drl | 317 ++++++------ .../eventmanager/ControlLoopEventManager.java | 133 ++--- .../eventmanager/ControlLoopOperationManager.java | 24 +- .../eventmanager/LockCallbackWorkingMemory.java | 80 +++ .../eventmanager/ControlLoopEventManagerTest.java | 226 ++++++--- .../LockCallbackWorkingMemoryTest.java | 96 ++++ .../java/org/onap/policy/guard/LockCallback.java | 29 -- .../java/org/onap/policy/guard/PolicyGuard.java | 241 --------- .../java/org/onap/policy/guard/TargetLock.java | 37 -- .../org/onap/policy/guard/impl/PnfTargetLock.java | 47 -- .../org/onap/policy/guard/impl/TargetLockImpl.java | 86 ---- .../org/onap/policy/guard/impl/VmTargetLock.java | 47 -- .../org/onap/policy/guard/impl/VnfTargetLock.java | 47 -- .../org/onap/policy/guard/PolicyGuardTest.java | 335 ------------- .../main/resources/__closedLoopControlName__.drl | 558 +++++++++++---------- .../template/demo/ControlLoopFailureTest.java | 39 +- 16 files changed, 893 insertions(+), 1449 deletions(-) create mode 100644 controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemory.java create mode 100644 controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemoryTest.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/LockCallback.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/TargetLock.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PnfTargetLock.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/TargetLockImpl.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VmTargetLock.java delete mode 100644 controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VnfTargetLock.java delete mode 100644 controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java diff --git a/controlloop/common/controller-usecases/src/main/resources/usecases.drl b/controlloop/common/controller-usecases/src/main/resources/usecases.drl index 4adf74064..fb6812a88 100644 --- a/controlloop/common/controller-usecases/src/main/resources/usecases.drl +++ b/controlloop/common/controller-usecases/src/main/resources/usecases.drl @@ -35,6 +35,7 @@ import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NewEventStatus; import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager; +import org.onap.policy.controlloop.eventmanager.LockCallbackWorkingMemory; import org.onap.policy.controlloop.utils.ControlLoopUtils; import org.onap.policy.controlloop.actor.so.SoActorServiceProvider; import org.onap.policy.controlloop.actor.cds.CdsActorServiceProvider; @@ -53,6 +54,7 @@ import org.onap.policy.appclcm.LcmCommonHeader; import org.onap.policy.cds.CdsResponse; import org.onap.policy.cds.client.CdsProcessorGrpcClient; import org.onap.policy.cds.properties.CdsServerProperties; +import org.onap.policy.drools.utils.Pair; import org.onap.policy.sdnr.PciRequestWrapper; import org.onap.policy.sdnr.PciResponseWrapper; import org.onap.policy.sdnr.PciRequest; @@ -66,10 +68,7 @@ import org.onap.policy.so.SoResponseWrapper; import org.onap.policy.sdnc.SdncRequest; import org.onap.policy.sdnc.SdncManager; import org.onap.policy.sdnc.SdncResponse; -import org.onap.policy.guard.PolicyGuard; -import org.onap.policy.guard.PolicyGuard.LockResult; -import org.onap.policy.guard.TargetLock; -import org.onap.policy.guard.GuardResult; +import org.onap.policy.drools.core.lock.Lock; import org.onap.policy.guard.PolicyGuardRequest; import org.onap.policy.guard.PolicyGuardResponse; import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes; @@ -113,7 +112,7 @@ rule "INSERT.PARAMS" then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." + logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." + drools.getRule().getName(), $params.getControlLoopYaml()); end @@ -164,7 +163,7 @@ rule "EVENT" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) ) then @@ -204,7 +203,7 @@ rule "EVENT" // ControlLoopEventManager manager = new ControlLoopEventManager($clName, $event.getRequestId()); // - // Determine if EventManager can actively process the event + // Determine if EventManager can actively process the event // (i.e. syntax, is_closed_loop_disabled checks etc.) // VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event); @@ -283,9 +282,9 @@ rule "EVENT.MANAGER" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired ) then @@ -362,10 +361,10 @@ rule "EVENT.MANAGER" // // Unlock the target // - TargetLock lock = $manager.unlockCurrentOperation(); - if (lock != null) { - logger.debug("{}: {}: retracting lock=", $clName, - $params.getPolicyName() + "." + drools.getRule().getName(), lock); + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + logger.debug("{}: {}.{}: retracting lock={}", $clName, + $params.getPolicyName(), drools.getRule().getName(), lock); retract(lock); } // @@ -375,9 +374,9 @@ rule "EVENT.MANAGER" $clName, $params.getPolicyName() + "." + drools.getRule().getName()); retract($manager.getOnsetEvent()); - + // don't retract manager, etc. - a clean-up rule will do that - + // // TODO - what if we get subsequent Events for this RequestId? // By default, it will all start over again. May be confusing for Ruby. @@ -407,10 +406,10 @@ rule "EVENT.MANAGER" // // Unlock the target // - TargetLock lock = $manager.unlockCurrentOperation(); - if (lock != null) { - logger.debug("{}: {}: retracting lock=", $clName, - $params.getPolicyName() + "." + drools.getRule().getName(), lock); + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + logger.debug("{}: {}.{}: retracting lock={}", $clName, + $params.getPolicyName(), drools.getRule().getName(), lock); retract(lock); } // @@ -420,7 +419,7 @@ rule "EVENT.MANAGER" $clName, $params.getPolicyName() + "." + drools.getRule().getName()); retract($manager.getOnsetEvent()); - + // don't retract manager, etc. - a clean-up rule will do that } } @@ -433,57 +432,39 @@ rule "EVENT.MANAGER" // // Let's ask for a lock right away // - LockResult result = $manager.lockCurrentOperation(); - logger.info("{}: {}: guard lock acquired={}", - $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - result.getB()); - if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) { - // - // insert the operation into memory - // - insert(operation); - - // - // insert operation timeout object - // - ControlLoopTimer opTimer = new ControlLoopTimer(); - opTimer.setTimerType("Operation"); - opTimer.setClosedLoopControlName($event.getClosedLoopControlName()); - opTimer.setRequestId($event.getRequestId().toString()); - Integer timeout = operation.getOperationTimeout(); - opTimer.setDelay(timeout > 0 ? timeout.toString() + "s" : $clTimer.getDelay()); - insert(opTimer); - - // - // Insert lock into memory - // - insert(result.getB()); + logger.info("{}: {}.{}: requesting lock for operation={}", + $clName, $params.getPolicyName(), drools.getRule().getName(), + operation); + + Pair oldNew = $manager.lockCurrentOperation( + new LockCallbackWorkingMemory($params.getClosedLoopControlName(), drools.getWorkingMemory())); + if(oldNew.first() != null) { + logger.debug("{}: {}.{}: retracting lock={}", $clName, + $params.getPolicyName(), drools.getRule().getName(), oldNew.first()); + retract(oldNew.first()); + } + if(oldNew.second() != null) { + logger.debug("{}: {}.{}: inserting lock={}", $clName, + $params.getPolicyName(), drools.getRule().getName(), oldNew.second()); + insert(oldNew.second()); } - else { - logger.debug("The target resource {} is already processing", - $event.getAai().get($event.getTarget())); - notification = new VirtualControlLoopNotification($event); - notification.setNotification(ControlLoopNotificationType.REJECTED); - notification.setMessage("The target " + $event.getAai().get($event.getTarget()) - + " is already locked"); - notification.setFrom("policy"); - notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); - notification.setPolicyScope($params.getPolicyScope()); - notification.setPolicyVersion($params.getPolicyVersion()); - PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); + // + // insert the operation into memory + // + insert(operation); - retract($event); - - // don't retract manager, etc. - a clean-up rule will do that + // + // insert operation timeout object + // + ControlLoopTimer opTimer = new ControlLoopTimer(); + opTimer.setTimerType("Operation"); + opTimer.setClosedLoopControlName($event.getClosedLoopControlName()); + opTimer.setRequestId($event.getRequestId().toString()); + Integer timeout = operation.getOperationTimeout(); + opTimer.setDelay(timeout > 0 ? timeout.toString() + "s" : $clTimer.getDelay()); + insert(opTimer); - if(result.getB() != null) { - retract(result.getB()); - } - } - logger.info("{}: {}: starting operation={}", - $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - operation); } else { // // Probably waiting for abatement @@ -508,12 +489,49 @@ rule "EVENT.MANAGER" PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); retract($event); - + // don't retract manager, etc. - a clean-up rule will do that } end +/* +* +* Lock denied +* +*/ +rule "EVENT.MANAGER.OPERATION.LOCK.DENIED" + when + $params : ControlLoopParams( $clName : getClosedLoopControlName() ) + $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + requestId == $event.getRequestId() ) + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + onset.getRequestId() == $event.getRequestId(), "None".equalsIgnoreCase(getGuardApprovalStatus()) ) + $lock : Lock (ownerKey == $event.getRequestId().toString(), isUnavailable()) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}.{}: event={} manager={} operation={} lock={}", + $clName, $params.getPolicyName(), drools.getRule().getName(), + $event, $manager, $operation, $lock); + + logger.debug("The target resource {} is already processing", $event.getAai().get($event.getTarget())); + VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); + notification.setNotification(ControlLoopNotificationType.REJECTED); + notification.setMessage("The target " + $event.getAai().get($event.getTarget()) + " is already locked"); + notification.setFrom("policy"); + notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); + notification.setPolicyScope($params.getPolicyScope()); + notification.setPolicyVersion($params.getPolicyVersion()); + + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); + + retract($event); + + // don't retract manager, etc. - a clean-up rule will do that +end + /* * * Guard Permitted, let's send request to the actor. @@ -523,19 +541,18 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) ) - $lock : TargetLock (requestId == $event.getRequestId()) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} operation={} lock={}", + logger.info("{}: {}: event={} manager={} operation={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock); + $event, $manager, $operation); Object request = null; boolean caughtException = false; @@ -573,7 +590,7 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" } break; case "SO": - // at this point the AAI named query request should have already been made, the response + // at this point the AAI named query request should have already been made, the response // recieved and used in the construction of the SO Request which is stored in operationRequest if(request instanceof SoRequest) { @@ -583,8 +600,8 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" drools.getWorkingMemory().insert(wrapper); } } - SoActorServiceProvider.sendRequest($event.getRequestId().toString(), - new mySoCallback(), + SoActorServiceProvider.sendRequest($event.getRequestId().toString(), + new mySoCallback(), request, PolicyEngineConstants.getManager().getEnvironmentProperty("so.url"), PolicyEngineConstants.getManager().getEnvironmentProperty("so.username"), @@ -594,7 +611,7 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" case "VFC": if (request instanceof VfcRequest) { class myVfcCallback implements VfcManager.VfcCallback { - + public void onResponse(VfcResponse responseError) { drools.getWorkingMemory().insert(responseError); } @@ -613,23 +630,23 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" PolicyEngineConstants.getManager().deliver("SDNR-CL", request); } break; - + case "SDNC": if (request instanceof SdncRequest) { class mySdncCallback implements SdncManager.SdncCallback { public void onCallback(SdncResponse response) { drools.getWorkingMemory().insert(response); } - } + } // Start SDNC thread - Thread t = new Thread(new SdncManager(new mySdncCallback(), + Thread t = new Thread(new SdncManager(new mySdncCallback(), (SdncRequest)request, PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.url"), PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.username"), PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.password"))); t.start(); } - break; + break; case "CDS": @@ -656,7 +673,6 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" } } break; - } } else { // @@ -728,11 +744,11 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), - onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" ) - $lock : TargetLock (requestId == $event.getRequestId()) + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + onset.getRequestId() == $event.getRequestId(), "None".equalsIgnoreCase(getGuardApprovalStatus()) ) + $lock : Lock (ownerKey == $event.getRequestId().toString(), isActive()) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); @@ -745,7 +761,7 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED" // VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.OPERATION); - notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " " + notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()); notification.setHistory($operation.getHistory()); notification.setFrom("policy"); @@ -813,22 +829,21 @@ end rule "GUARD.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $lock : TargetLock (requestId == $event.getRequestId()) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) $guardResponse : PolicyGuardResponse(requestId == $event.getRequestId(), $operation.policy.recipe == operation) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}", + logger.info("{}: {}: event={} manager={} operation={} opTimer={} guardResponse={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $opTimer, $guardResponse); + $event, $manager, $operation, $opTimer, $guardResponse); //we will permit the operation if there was no Guard for it @@ -882,23 +897,22 @@ end rule "APPC.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : Response( getCommonHeader().RequestId == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $opTimer, $response); + $event, $manager, $operation, $opTimer, $response); // // Get the result of the operation // @@ -1000,23 +1014,22 @@ end rule "APPC.LCM.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // // Get the result of the operation @@ -1109,23 +1122,22 @@ end rule "SO.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : SoResponseWrapper(requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation // @@ -1197,22 +1209,21 @@ end rule "VFC.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation // @@ -1276,16 +1287,15 @@ rule "SDNC.RESPONSE" $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation // @@ -1353,16 +1363,15 @@ rule "${policyName}.CDS.RESPONSE" onset.getRequestId() == $event.getRequestId() ) $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : CdsResponse( requestId == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation PolicyResult policyResult = $operation.onResponse($response); @@ -1444,20 +1453,19 @@ rule "EVENT.MANAGER.OPERATION.TIMEOUT" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", expired ) - $lock : TargetLock (requestId == $event.getRequestId()) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer); + $event, $manager, $operation, $operation, $opTimer); // // Tell it its timed out @@ -1511,9 +1519,9 @@ rule "EVENT.MANAGER.TIMEOUT" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) $event : VirtualControlLoopEvent( closedLoopControlName == $clName ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", expired ) then @@ -1553,13 +1561,11 @@ rule "EVENT.MANAGER.CLEANUP" when $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestId() ) $operations : LinkedList() - from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName, + from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName, onset.getRequestId() == $requestId ) ) $timers : LinkedList() - from collect( ControlLoopTimer( closedLoopControlName == $clName, + from collect( ControlLoopTimer( closedLoopControlName == $clName, requestId == $requestId.toString() ) ) - $locks : LinkedList() - from collect( TargetLock (requestId == $requestId) ) not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) ) then @@ -1570,6 +1576,14 @@ rule "EVENT.MANAGER.CLEANUP" $clName, drools.getRule().getName(), $manager, $timers.size(), $operations.size()); + // + // Retract lock by invoking unlock() + // + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + retract(lock); + } + // // Retract EVERYTHING // @@ -1581,14 +1595,6 @@ rule "EVENT.MANAGER.CLEANUP" for(Object timer: $timers) { retract((ControlLoopTimer) timer); } - for(Object lock: $locks) { - TargetLock tgt = (TargetLock) lock; - // - // Ensure we release the lock - // - PolicyGuard.unlockTarget(tgt); - retract(tgt); - } end /* @@ -1619,23 +1625,22 @@ end rule "SDNR.RESPONSE" when $params : ControlLoopParams( $clName : getClosedLoopControlName() ) - $event : VirtualControlLoopEvent( closedLoopControlName == $clName, + $event : VirtualControlLoopEvent( closedLoopControlName == $clName, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, $params.getPolicyName() + "." + drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $clName, $params.getPolicyName() + "." + drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // // Get the result of the operation diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java index f6cfe5594..6afb08d76 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java @@ -58,18 +58,18 @@ import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.policy.FinalResult; import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.processor.ControlLoopProcessor; +import org.onap.policy.drools.core.lock.Lock; +import org.onap.policy.drools.core.lock.LockCallback; +import org.onap.policy.drools.core.lock.LockImpl; +import org.onap.policy.drools.core.lock.LockState; import org.onap.policy.drools.system.PolicyEngineConstants; -import org.onap.policy.guard.GuardResult; -import org.onap.policy.guard.LockCallback; -import org.onap.policy.guard.PolicyGuard; -import org.onap.policy.guard.PolicyGuard.LockResult; -import org.onap.policy.guard.TargetLock; +import org.onap.policy.drools.utils.Pair; import org.onap.policy.rest.RestManager; import org.onap.policy.so.util.Serialization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ControlLoopEventManager implements LockCallback, Serializable { +public class ControlLoopEventManager implements Serializable { public static final String PROV_STATUS_ACTIVE = "ACTIVE"; private static final String VM_NAME = "VM_NAME"; private static final String VNF_NAME = "VNF_NAME"; @@ -121,7 +121,7 @@ public class ControlLoopEventManager implements LockCallback, Serializable { private LinkedList controlLoopHistory = new LinkedList<>(); private ControlLoopOperationManager currentOperation = null; private ControlLoopOperationManager lastOperationManager = null; - private transient TargetLock targetLock = null; + private transient Lock targetLock = null; private AaiGetVnfResponse vnfResponse = null; private AaiGetVserverResponse vserverResponse = null; private boolean useTargetLock = true; @@ -140,6 +140,12 @@ public class ControlLoopEventManager implements LockCallback, Serializable { requiredAAIKeys.add(VM_NAME); } + /** + * Constructs the object. + * + * @param closedLoopControlName name of the control loop + * @param requestId ID of the request with which this manager is associated + */ public ControlLoopEventManager(String closedLoopControlName, UUID requestId) { this.closedLoopControlName = closedLoopControlName; this.requestId = requestId; @@ -472,9 +478,11 @@ public class ControlLoopEventManager implements LockCallback, Serializable { // this.lastOperationManager = this.currentOperation; this.currentOperation = null; + // - // TODO: Release our lock + // Don't release the lock - it may be re-used by the next operation // + return; } logger.debug("Cannot finish current operation {} does not match given operation {}", @@ -487,77 +495,75 @@ public class ControlLoopEventManager implements LockCallback, Serializable { /** * Obtain a lock for the current operation. * - * @return the lock result + * @param callback call-back to be invoked when the lock state changes + * @return a pair containing the old lock and the new lock, either of which may be null * @throws ControlLoopException if an error occurs */ - public synchronized LockResult lockCurrentOperation() throws ControlLoopException { + public synchronized Pair lockCurrentOperation(LockCallback callback) throws ControlLoopException { // // Sanity check // if (this.currentOperation == null) { throw new ControlLoopException("Do not have a current operation."); } + // - // Not using target locks? Create and return a lock w/o actually locking. + // Release the old lock if it's for a different resource. // - if (!this.useTargetLock) { - TargetLock lock = PolicyGuard.createTargetLock(this.currentOperation.policy.getTarget().getType(), - this.currentOperation.getTargetEntity(), this.onset.getRequestId(), this); - this.targetLock = lock; - return LockResult.createLockResult(GuardResult.LOCK_ACQUIRED, lock); + Lock oldLock = null; + if (this.targetLock != null + && !this.targetLock.getResourceId().equals(this.currentOperation.getTargetEntity())) { + logger.debug("{}: different resource - releasing old lock", getClosedLoopControlName()); + oldLock = this.targetLock; + this.targetLock = null; } + + // keep the lock a little longer than the operation, including retries + int optimeout = Math.max(1, this.currentOperation.getOperationTimeout()); + int nattempts = 1 + Math.max(0, this.currentOperation.getMaxRetries()); + int holdSec = optimeout * nattempts + ADDITIONAL_LOCK_SEC; + // // Have we acquired it already? // if (this.targetLock != null) { - // - // TODO: Make sure the current lock is for the same target. - // Currently, it should be. But in the future it may not. - // - GuardResult result = PolicyGuard.lockTarget(targetLock, - this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC); - return new LockResult<>(result, this.targetLock); + // we have the lock - just extend it + this.targetLock.extend(holdSec, callback); + return new Pair<>(oldLock, null); + + } else if (this.useTargetLock) { + this.targetLock = createRealLock(this.currentOperation.getTargetEntity(), this.onset.getRequestId(), + holdSec, callback); + return new Pair<>(oldLock, this.targetLock); + } else { - // - // Ask the Guard - // - LockResult lockResult = PolicyGuard.lockTarget( - this.currentOperation.policy.getTarget().getType(), this.currentOperation.getTargetEntity(), - this.onset.getRequestId(), this, this.currentOperation.getOperationTimeout() + ADDITIONAL_LOCK_SEC); - // - // Was it acquired? - // - if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) { - // - // Yes, let's save it - // - this.targetLock = lockResult.getB(); - } - return lockResult; + // Not using target locks - create a lock w/o actually locking. + logger.debug("{}: not using target locking; using pseudo locks", getClosedLoopControlName()); + this.targetLock = createPseudoLock(this.currentOperation.getTargetEntity(), this.onset.getRequestId(), + holdSec, callback); + + // Note: no need to invoke callback, as the lock is already ACTIVE + + return new Pair<>(oldLock, this.targetLock); } } /** - * Release the lock for the current operation. + * Releases the lock for the current operation, deleting it from working memory. * - * @return the target lock + * @return the lock, if the operation was locked, {@code null} otherwise */ - public synchronized TargetLock unlockCurrentOperation() { + public synchronized Lock unlockCurrentOperation() { if (this.targetLock == null) { return null; } - TargetLock returnLock = this.targetLock; + Lock lock = this.targetLock; this.targetLock = null; - // - // if using target locking unlock before returning - // - if (this.useTargetLock) { - PolicyGuard.unlockTarget(returnLock); - } - // always return the old target lock so rules can retract it - return returnLock; + lock.free(); + + return lock; } public enum NewEventStatus { @@ -1032,18 +1038,6 @@ public class ControlLoopEventManager implements LockCallback, Serializable { return enginePropertyValue; } - @Override - public boolean isActive() { - // TODO - return true; - } - - @Override - public boolean releaseLock() { - // TODO - return false; - } - @Override public String toString() { return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestId=" + requestId @@ -1097,4 +1091,17 @@ public class ControlLoopEventManager implements LockCallback, Serializable { } + + // the following methods may be overridden by junit tests + + protected Lock createRealLock(String targetEntity, UUID requestId, int holdSec, LockCallback callback) { + return PolicyEngineConstants.getManager().createLock(targetEntity, requestId.toString(), holdSec, callback, + false); + } + + // note: the "callback" is required, because it will be invoked when lock.extend() is + // invoked + protected Lock createPseudoLock(String targetEntity, UUID requestId, int holdSec, LockCallback callback) { + return new LockImpl(LockState.ACTIVE, targetEntity, requestId.toString(), holdSec, callback); + } } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java index eb1901937..62bd0c1e9 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java @@ -963,7 +963,7 @@ public class ControlLoopOperationManager implements Serializable { // // Check if there were no retries specified // - if (policy.getRetry() == null || policy.getRetry() == 0) { + if (getMaxRetries() < 1) { // // The result is the failure // @@ -972,7 +972,7 @@ public class ControlLoopOperationManager implements Serializable { // // Check retries // - if (this.isRetriesMaxedOut()) { + if (this.attempts > getMaxRetries()) { // // No more attempts allowed, reset // that our actual result is failure due to retries @@ -1016,7 +1016,7 @@ public class ControlLoopOperationManager implements Serializable { // // Check if we have maxed out on retries // - if (this.policy.getRetry() == null || this.policy.getRetry() < 1) { + if (getMaxRetries() < 1) { // // No retries are allowed, so check have we even made // one attempt to execute the operation? @@ -1037,7 +1037,7 @@ public class ControlLoopOperationManager implements Serializable { // // Have we maxed out on retries? // - if (this.attempts > this.policy.getRetry()) { + if (this.attempts > getMaxRetries()) { if (this.policyResult == null) { this.policyResult = PolicyResult.FAILURE_RETRIES; } @@ -1046,15 +1046,13 @@ public class ControlLoopOperationManager implements Serializable { } } - private boolean isRetriesMaxedOut() { - if (policy.getRetry() == null || policy.getRetry() == 0) { - // - // There were NO retries specified, so declare - // this as completed. - // - return (this.attempts > 0); - } - return (this.attempts > policy.getRetry()); + /** + * Gets the maximum number of retries. + * + * @return the maximum number of retries, or {@code 0}, if not specified + */ + public int getMaxRetries() { + return (policy.getRetry() != null ? policy.getRetry() : 0); } private void storeOperationInDataBase() { diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemory.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemory.java new file mode 100644 index 000000000..738d3b922 --- /dev/null +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemory.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.controlloop.eventmanager; + +import lombok.Getter; +import org.drools.core.WorkingMemory; +import org.kie.api.runtime.rule.FactHandle; +import org.onap.policy.drools.core.lock.Lock; +import org.onap.policy.drools.core.lock.LockCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Lock call-back that updates working memory. + */ +@Getter +public class LockCallbackWorkingMemory implements LockCallback { + private static final Logger logger = LoggerFactory.getLogger(LockCallbackWorkingMemory.class); + + /** + * Name to be logged when the lock is updated. + */ + private final String name; + + /** + * Working memory to be updated when the lock is notified. + */ + private final WorkingMemory workingMemory; + + + /** + * Constructs the object. + * + * @param name name to be logged when the lock is updated + * @param workingMemory working memory to be updated when the lock is notified + */ + public LockCallbackWorkingMemory(String name, WorkingMemory workingMemory) { + this.name = name; + this.workingMemory = workingMemory; + } + + @Override + public void lockAvailable(Lock lock) { + notifySession(lock); + } + + @Override + public void lockUnavailable(Lock lock) { + notifySession(lock); + } + + /** + * Notifies the session that the lock has been updated. + */ + private void notifySession(Lock lock) { + FactHandle fact = workingMemory.getFactHandle(lock); + if (fact != null) { + logger.debug("{}: updating lock={}", name, lock); + workingMemory.update(fact, lock); + } + } +} diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java index 0b27ffa49..8efdb1fcb 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java @@ -25,12 +25,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.HashMap; @@ -65,14 +72,14 @@ import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NewEventStatus; import org.onap.policy.controlloop.policy.ControlLoopPolicy; import org.onap.policy.controlloop.policy.PolicyResult; +import org.onap.policy.drools.core.lock.Lock; +import org.onap.policy.drools.core.lock.LockCallback; import org.onap.policy.drools.system.PolicyEngineConstants; -import org.onap.policy.guard.GuardResult; -import org.onap.policy.guard.PolicyGuard; -import org.onap.policy.guard.PolicyGuard.LockResult; -import org.onap.policy.guard.TargetLock; +import org.onap.policy.drools.utils.Pair; import org.powermock.reflect.Whitebox; public class ControlLoopEventManagerTest { + private static final String TARGET_LOCK_FIELD = "targetLock"; private static final String PROCESS_VSERVER_RESPONSE = "processVServerResponse"; private static final String ONSET_ONE = "onsetOne"; private static final String VSERVER_NAME = "vserver.vserver-name"; @@ -107,6 +114,7 @@ public class ControlLoopEventManagerTest { public ExpectedException thrown = ExpectedException.none(); private VirtualControlLoopEvent onset; + private LockCallback callback; /** * Set up test class. @@ -130,6 +138,8 @@ public class ControlLoopEventManagerTest { */ @Before public void setUp() { + callback = mock(LockCallback.class); + onset = new VirtualControlLoopEvent(); onset.setClosedLoopControlName("ControlLoop-vUSP"); onset.setRequestId(UUID.randomUUID()); @@ -414,8 +424,6 @@ public class ControlLoopEventManagerTest { assertNull(clem.getAbatementEvent()); assertNull(clem.getProcessor()); - assertEquals(true, clem.isActive()); - assertEquals(false, clem.releaseLock()); assertEquals(true, clem.isControlLoopTimedOut()); assertNull(clem.unlockCurrentOperation()); @@ -441,11 +449,6 @@ public class ControlLoopEventManagerTest { @Test public void testActivationYaml() throws IOException { - InputStream is = new FileInputStream(new File(TEST_YAML)); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - - InputStream isBad = new FileInputStream(new File("src/test/resources/notutf8.yaml")); - final String yamlStringBad = IOUtils.toString(isBad, StandardCharsets.UTF_8); UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent event = new VirtualControlLoopEvent(); @@ -470,10 +473,17 @@ public class ControlLoopEventManagerTest { assertEquals(ControlLoopNotificationType.REJECTED, notificationEmpty.getNotification()); // Bad YAML should fail + InputStream isBad = new FileInputStream(new File("src/test/resources/notutf8.yaml")); + final String yamlStringBad = IOUtils.toString(isBad, StandardCharsets.UTF_8); + VirtualControlLoopNotification notificationBad = manager.activate(yamlStringBad, event); assertNotNull(notificationBad); assertEquals(ControlLoopNotificationType.REJECTED, notificationBad.getNotification()); + + InputStream is = new FileInputStream(new File(TEST_YAML)); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, event); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -486,9 +496,6 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopFinal() throws Exception { - InputStream is = new FileInputStream(new File(TEST_YAML)); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent event = new VirtualControlLoopEvent(); event.setClosedLoopControlName(TWO_ONSET_TEST); @@ -509,6 +516,10 @@ public class ControlLoopEventManagerTest { .hasMessage("No onset event for ControlLoopEventManager."); manager.setActivated(false); + + InputStream is = new FileInputStream(new File(TEST_YAML)); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, event); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -552,9 +563,6 @@ public class ControlLoopEventManagerTest { @Test public void testProcessControlLoop() throws Exception { - InputStream is = new FileInputStream(new File(TEST_YAML)); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent event = new VirtualControlLoopEvent(); event.setClosedLoopControlName(TWO_ONSET_TEST); @@ -575,6 +583,10 @@ public class ControlLoopEventManagerTest { .hasMessage("No onset event for ControlLoopEventManager."); manager.setActivated(false); + + InputStream is = new FileInputStream(new File(TEST_YAML)); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, event); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -620,21 +632,10 @@ public class ControlLoopEventManagerTest { @Test public void testFinishOperation() throws Exception { - InputStream is = new FileInputStream(new File("src/test/resources/testSOactor.yaml")); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - InputStream isStd = new FileInputStream(new File(TEST_YAML)); final String yamlStringStd = IOUtils.toString(isStd, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.setClosedLoopControlName(TWO_ONSET_TEST); - event.setRequestId(requestId); - event.setTarget(VNF_ID); - event.setClosedLoopAlarmStart(Instant.now()); - event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - event.setAai(new HashMap<>()); - event.getAai().put(VNF_ID, ONSET_ONE); + VirtualControlLoopEvent event = makeEvent(); ControlLoopEventManager manager = makeManager(event); ControlLoopEventManager manager2 = manager; @@ -646,15 +647,14 @@ public class ControlLoopEventManagerTest { .hasMessage("No operation to finish."); manager.setActivated(false); + + InputStream is = new FileInputStream(new File("src/test/resources/testSOactor.yaml")); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, event); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); - assertThatThrownBy(manager2::lockCurrentOperation).isInstanceOf(ControlLoopException.class) - .hasMessage("Do not have a current operation."); - - assertNull(manager.unlockCurrentOperation()); - // serialize and de-serialize manager manager = Serializer.roundTrip(manager); @@ -662,23 +662,6 @@ public class ControlLoopEventManagerTest { assertNotNull(clom); assertNull(clom.getOperationResult()); - LockResult lockLock = manager.lockCurrentOperation(); - assertNotNull(lockLock); - assertEquals(GuardResult.LOCK_ACQUIRED, lockLock.getA()); - - LockResult lockLockAgain = manager.lockCurrentOperation(); - assertNotNull(lockLockAgain); - assertEquals(GuardResult.LOCK_ACQUIRED, lockLockAgain.getA()); - assertEquals(lockLock.getB(), lockLockAgain.getB()); - - assertEquals(lockLock.getB(), manager.unlockCurrentOperation()); - assertNull(manager.unlockCurrentOperation()); - - lockLock = manager.lockCurrentOperation(); - assertNotNull(lockLock); - PolicyGuard.unlockTarget(lockLock.getB()); - assertEquals(lockLock.getB(), manager.unlockCurrentOperation()); - clom.startOperation(event); // This call should be exception free @@ -697,10 +680,98 @@ public class ControlLoopEventManagerTest { } @Test - public void testOnNewEvent() throws Exception { - InputStream is = new FileInputStream(new File(TEST_YAML)); + public void testLockCurrentOperation_testUnlockCurrentOperation() throws Exception { + VirtualControlLoopEvent event = makeEvent(); + + ControlLoopEventManager manager = makeManager(event); + + manager.setActivated(false); + + InputStream is = new FileInputStream(new File("src/test/resources/testSOactor.yaml")); final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, event); + assertNotNull(notification); + assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); + + ControlLoopEventManager manager2 = manager; + assertThatThrownBy(() -> manager2.lockCurrentOperation(callback)).isInstanceOf(ControlLoopException.class) + .hasMessage("Do not have a current operation."); + + assertNull(manager.unlockCurrentOperation()); + + ControlLoopOperationManager clom = manager.processControlLoop(); + assertNotNull(clom); + assertNull(clom.getOperationResult()); + + Pair lockPair = manager.lockCurrentOperation(callback); + assertNull(lockPair.first()); + assertNotNull(lockPair.second()); + + // pseudo lock - session should NOT have been notified of the change + verify(callback, never()).lockAvailable(any()); + verify(callback, never()).lockUnavailable(any()); + + // repeat - should cause an extension + Lock lock = lockPair.second(); + lockPair = manager.lockCurrentOperation(callback); + + /* + * even with a pseudo lock, the session should have been notified that it was + * extended + */ + + verify(callback).lockAvailable(lock); + + assertSame(lock, manager.unlockCurrentOperation()); + + assertNull(lockPair.first()); + assertNull(lockPair.second()); + + // force it to use a pseudo lock + manager.setUseTargetLock(false); + lockPair = manager.lockCurrentOperation(callback); + assertNull(lockPair.first()); + assertNotNull(lockPair.second()); + + lock = lockPair.second(); + + lockPair = manager.lockCurrentOperation(callback); + assertNull(lockPair.first()); + assertNull(lockPair.second()); + + // first lock uses a pseudo lock, so it will only update when extended + verify(callback).lockAvailable(lock); + + // force it to re-create the lock due to change in resource ID + lock = mock(Lock.class); + when(lock.getResourceId()).thenReturn("different"); + Whitebox.setInternalState(manager, TARGET_LOCK_FIELD, lock); + + lockPair = manager.lockCurrentOperation(callback); + assertSame(lock, lockPair.first()); + assertNotNull(lockPair.second()); + + lock = lockPair.second(); + + lockPair = manager.lockCurrentOperation(callback); + assertNull(lockPair.first()); + assertNull(lockPair.second()); + + // first lock uses a pseudo lock, so it won't do an update + verify(callback).lockAvailable(lock); + + assertSame(lock, manager.unlockCurrentOperation()); + assertNull(manager.unlockCurrentOperation()); + + // try again - this time don't return the fact handle- no change in count + lockPair = manager.lockCurrentOperation(callback); + assertNull(lockPair.first()); + assertNotNull(lockPair.second()); + } + + @Test + public void testOnNewEvent() throws Exception { UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); @@ -721,6 +792,10 @@ public class ControlLoopEventManagerTest { abatedEvent.getAai().put(VNF_NAME, ONSET_ONE); ControlLoopEventManager manager = makeManager(onsetEvent); + + InputStream is = new FileInputStream(new File(TEST_YAML)); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -816,9 +891,6 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout() throws IOException { - InputStream is = new FileInputStream(new File(TEST_YAML)); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); @@ -833,6 +905,9 @@ public class ControlLoopEventManagerTest { assertTrue(0 == manager.getControlLoopTimeout(null)); assertTrue(120 == manager.getControlLoopTimeout(120)); + InputStream is = new FileInputStream(new File(TEST_YAML)); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -842,9 +917,6 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout_ZeroTimeout() throws IOException { - InputStream is = new FileInputStream(new File("src/test/resources/test-zero-timeout.yaml")); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); @@ -857,6 +929,9 @@ public class ControlLoopEventManagerTest { ControlLoopEventManager manager = makeManager(onsetEvent); + InputStream is = new FileInputStream(new File("src/test/resources/test-zero-timeout.yaml")); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -867,9 +942,6 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout_NullTimeout() throws IOException { - InputStream is = new FileInputStream(new File("src/test/resources/test-null-timeout.yaml")); - final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); - UUID requestId = UUID.randomUUID(); VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); @@ -882,6 +954,9 @@ public class ControlLoopEventManagerTest { ControlLoopEventManager manager = makeManager(onsetEvent); + InputStream is = new FileInputStream(new File("src/test/resources/test-null-timeout.yaml")); + final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8); + VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent); assertNotNull(notification); assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); @@ -1258,8 +1333,33 @@ public class ControlLoopEventManagerTest { assertNotNull(aaiCqResponse); } + private VirtualControlLoopEvent makeEvent() { + UUID requestId = UUID.randomUUID(); + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(TWO_ONSET_TEST); + event.setRequestId(requestId); + event.setTarget(VNF_ID); + event.setClosedLoopAlarmStart(Instant.now()); + event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); + event.setAai(new HashMap<>()); + event.getAai().put(VNF_ID, ONSET_ONE); + return event; + } private ControlLoopEventManager makeManager(VirtualControlLoopEvent event) { - return new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId()); + return new MyManager(event.getClosedLoopControlName(), event.getRequestId()); + } + + private static class MyManager extends ControlLoopEventManager implements Serializable { + private static final long serialVersionUID = 1L; + + public MyManager(String closedLoopControlName, UUID requestId) { + super(closedLoopControlName, requestId); + } + + @Override + protected Lock createRealLock(String targetEntity, UUID requestId, int holdSec, LockCallback callback) { + return createPseudoLock(targetEntity, requestId, holdSec, callback); + } } } diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemoryTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemoryTest.java new file mode 100644 index 000000000..18ab15b5a --- /dev/null +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemoryTest.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.controlloop.eventmanager; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.drools.core.WorkingMemory; +import org.junit.Before; +import org.junit.Test; +import org.kie.api.runtime.rule.FactHandle; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.drools.core.lock.Lock; + +public class LockCallbackWorkingMemoryTest { + private static final String MY_NAME = "my-name"; + + @Mock + private WorkingMemory workingMemory; + + @Mock + private Lock lock; + + @Mock + private FactHandle fact; + + private LockCallbackWorkingMemory callback; + + + /** + * Initializes mocks and creates a call-back. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + when(workingMemory.getFactHandle(lock)).thenReturn(fact); + + callback = new LockCallbackWorkingMemory(MY_NAME, workingMemory); + } + + @Test + public void testLockCallbackWorkingMemory() { + assertEquals(MY_NAME, callback.getName()); + assertSame(workingMemory, callback.getWorkingMemory()); + } + + @Test + public void testLockAvailable() { + callback.lockAvailable(lock); + verify(workingMemory).update(fact, lock); + + // "remove" from working memory + when(workingMemory.getFactHandle(lock)).thenReturn(null); + callback.lockAvailable(lock); + + // should be no additional calls + verify(workingMemory).update(any(), any()); + } + + @Test + public void testLockUnavailable() { + callback.lockUnavailable(lock); + verify(workingMemory).update(fact, lock); + + // "remove" from working memory + when(workingMemory.getFactHandle(lock)).thenReturn(null); + callback.lockUnavailable(lock); + + // should be no additional calls + verify(workingMemory).update(any(), any()); + } + +} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/LockCallback.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/LockCallback.java deleted file mode 100644 index 2b33e0e57..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/LockCallback.java +++ /dev/null @@ -1,29 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard; - -public interface LockCallback { - - public boolean isActive(); - - public boolean releaseLock(); - -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java deleted file mode 100644 index 90e6e8753..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java +++ /dev/null @@ -1,241 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019 Tech Mahindra - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard; - -import java.util.UUID; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.drools.core.lock.PolicyResourceLockManager; -import org.onap.policy.guard.impl.PnfTargetLock; -import org.onap.policy.guard.impl.VmTargetLock; -import org.onap.policy.guard.impl.VnfTargetLock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PolicyGuard { - - private static final Logger logger = LoggerFactory.getLogger(PolicyGuard.class); - - /** - * Factory to access various objects. Can be changed for junit tests. - */ - private static Factory factory = new Factory(); - - public static class LockResult { - private A parameterA; - private B parameterB; - - public LockResult(A parameterA, B parameterB) { - this.parameterA = parameterA; - this.parameterB = parameterB; - } - - public A getA() { - return parameterA; - } - - public B getB() { - return parameterB; - } - - public static LockResult createLockResult(A parameterA, B parameterB) { - return new LockResult<>(parameterA, parameterB); - } - } - - private PolicyGuard() { - // Cannot instantiate this static class - } - - /** - * Get the factory. - * - * @return the factory used to access various objects - */ - protected static Factory getFactory() { - return factory; - } - - /** - * Sets the factory to be used by junit tests. - * @param factory factory - */ - protected static void setFactory(Factory factory) { - PolicyGuard.factory = factory; - } - - /** - * Create a lock. - * - * @param targetType the target type - * @param targetInstance the target instance - * @param requestId the request Id - * @return the TargetLock - * @throws IllegalArgumentException if an argument is null - */ - public static TargetLock createTargetLock(TargetType targetType, String targetInstance, - UUID requestId, LockCallback callback) { - switch (targetType) { - case PNF: - // - // Create the Lock object - // - return new PnfTargetLock(targetType, targetInstance, requestId, callback); - case VM: - // - // Create the Lock object - // - return new VmTargetLock(targetType, targetInstance, requestId, callback); - case VNF: - // - // Create the Lock object - // - return new VnfTargetLock(targetType, targetInstance, requestId, callback); - - case VFMODULE: - // - // Create the Lock object - // - return new VnfTargetLock(targetType, targetInstance, requestId, callback); - default: - logger.error("invalid target type {} for lock on {}", targetType, targetInstance); - return null; - } - } - - /** - * Lock a target. - * - * @param targetType the target type - * @param targetInstance the target instance - * @param requestId the request Id - * @param callback the LockCallback - * @param holdSec maximum number of seconds to hold the lock - * @return the LockResult - * @throws IllegalArgumentException if an argument is null - */ - public static LockResult lockTarget(TargetType targetType, String targetInstance, - UUID requestId, LockCallback callback, int holdSec) { - String owner = makeOwner(targetType, requestId); - boolean result = factory.getManager().lock(targetInstance, owner, holdSec); - if (!result) { - return LockResult.createLockResult(GuardResult.LOCK_DENIED, null); - } - - TargetLock lock = createTargetLock(targetType, targetInstance, requestId, callback); - if (lock == null) { - // - // Bad lock type: unlock and return exception result - // - factory.getManager().unlock(targetInstance, owner); - return LockResult.createLockResult(GuardResult.LOCK_EXCEPTION, null); - } else { - // - // Return result - // - logger.debug("Locked {}", lock); - return LockResult.createLockResult(GuardResult.LOCK_ACQUIRED, lock); - } - } - - /** - * Extends a lock on a target. - * @param lock current lock - * @param holdSec maximum number of seconds to hold the lock - * @return the result: acquired or denied - */ - public static GuardResult lockTarget(TargetLock lock, int holdSec) { - String owner = makeOwner(lock.getTargetType(), lock.getRequestId()); - - boolean result = factory.getManager().refresh(lock.getTargetInstance(), owner, holdSec); - - logger.debug("Lock {} extend {}", lock, result); - return (result ? GuardResult.LOCK_ACQUIRED : GuardResult.LOCK_DENIED); - } - - /** - * Unlock a target. - * - * @param lock the target lock to unlock - * @return true if the target is successfully unlocked, false - * otherwise - * @throws IllegalArgumentException if an argument is null - */ - public static boolean unlockTarget(TargetLock lock) { - String owner = makeOwner(lock.getTargetType(), lock.getRequestId()); - boolean result = factory.getManager().unlock(lock.getTargetInstance(), owner); - - if (result) { - logger.debug("Unlocked {}", lock); - return true; - } - - return false; - } - - /** - * Check if a target is locked. - * - * @param targetType the target type - * @param targetInstance the target instance - * @param requestId the request Id - * @return true if the target is locked, false otherwise - * @throws IllegalArgumentException if an argument is null - */ - public static boolean isLocked(TargetType targetType, String targetInstance, UUID requestId) { - String owner = makeOwner(targetType, requestId); - return factory.getManager().isLockedBy(targetInstance, owner); - } - - /** - * Combines the target type and request ID to yield a single, "owner" string. - * @param targetType target type - * @param requestID request id - * @return the "owner" of a resource - * @throws IllegalArgumentException if either argument is null - */ - private static String makeOwner(TargetType targetType, UUID requestId) { - if (targetType == null) { - throw new IllegalArgumentException("null targetType for lock request id " + requestId); - } - - if (requestId == null) { - throw new IllegalArgumentException("null requestID for lock type " + targetType); - } - - return targetType + ":" + requestId; - } - - /** - * Factory to access various objects. - */ - public static class Factory { - - /** - * Get the manager. - * - * @return the lock manager to be used - */ - public PolicyResourceLockManager getManager() { - return PolicyResourceLockManager.getInstance(); - } - } -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/TargetLock.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/TargetLock.java deleted file mode 100644 index eea46c3cc..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/TargetLock.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard; - -import java.util.UUID; - -import org.onap.policy.controlloop.policy.TargetType; - -public interface TargetLock { - - public UUID getLockId(); - - public TargetType getTargetType(); - - public String getTargetInstance(); - - public UUID getRequestId(); - -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PnfTargetLock.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PnfTargetLock.java deleted file mode 100644 index 8ddb5ffcf..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PnfTargetLock.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard.impl; - -import java.util.UUID; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.guard.LockCallback; - -public class PnfTargetLock extends TargetLockImpl { - - private static final long serialVersionUID = 2335897394577202732L; - - /** - * Construct an instance. - * - * @param type the target type - * @param target the target - * @param requestId the request Id - * @param callback the callback - */ - public PnfTargetLock(TargetType type, String target, UUID requestId, LockCallback callback) { - super(type, target, requestId, callback); - } - - @Override - public String toString() { - return "PnfTargetLock [" + super.toString() + "]"; - } -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/TargetLockImpl.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/TargetLockImpl.java deleted file mode 100644 index d406999f4..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/TargetLockImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard.impl; - -import java.io.Serializable; -import java.util.UUID; - -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.guard.LockCallback; -import org.onap.policy.guard.TargetLock; - -public class TargetLockImpl implements TargetLock, Serializable { - - private static final long serialVersionUID = 2335897394577202732L; - - private final UUID lockId; - private final TargetType targetType; - private final String target; - private final UUID requestId; - private final transient LockCallback callback; - - /** - * Construct an instance. - * - * @param type the target type - * @param target the target - * @param requestId the request Id - * @param callback the callback - */ - public TargetLockImpl(TargetType type, String target, UUID requestId, LockCallback callback) { - this.lockId = UUID.randomUUID(); - this.targetType = type; - this.target = target; - this.requestId = requestId; - this.callback = callback; - } - - @Override - public UUID getLockId() { - return this.lockId; - } - - - @Override - public TargetType getTargetType() { - return targetType; - } - - @Override - public String getTargetInstance() { - return target; - } - - @Override - public UUID getRequestId() { - return this.requestId; - } - - public LockCallback getCallback() { - return this.callback; - } - - @Override - public String toString() { - return "lockId=" + lockId + ", targetType=" + targetType + ", target=" + target + ", requestId=" - + requestId; - } -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VmTargetLock.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VmTargetLock.java deleted file mode 100644 index 2e612a03a..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VmTargetLock.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard.impl; - -import java.util.UUID; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.guard.LockCallback; - -public class VmTargetLock extends TargetLockImpl { - - private static final long serialVersionUID = 2335897394577202732L; - - /** - * Construct an instance. - * - * @param type the target type - * @param target the target - * @param requestId the request Id - * @param callback the callback - */ - public VmTargetLock(TargetType type, String target, UUID requestId, LockCallback callback) { - super(type, target, requestId, callback); - } - - @Override - public String toString() { - return "VmTargetLock [" + super.toString() + "]"; - } -} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VnfTargetLock.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VnfTargetLock.java deleted file mode 100644 index 2912c7ad4..000000000 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/VnfTargetLock.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard.impl; - -import java.util.UUID; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.guard.LockCallback; - -public class VnfTargetLock extends TargetLockImpl { - - private static final long serialVersionUID = 2335897394577202732L; - - /** - * Construct an instance. - * - * @param type the target type - * @param target the target - * @param requestId the request Id - * @param callback the callback - */ - public VnfTargetLock(TargetType type, String target, UUID requestId, LockCallback callback) { - super(type, target, requestId, callback); - } - - @Override - public String toString() { - return "VnfTargetLock [" + super.toString() + "]"; - } -} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java deleted file mode 100644 index 5f77d0331..000000000 --- a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java +++ /dev/null @@ -1,335 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * guard - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.guard; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.UUID; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.drools.core.lock.PolicyResourceLockManager; -import org.onap.policy.guard.PolicyGuard.Factory; -import org.onap.policy.guard.PolicyGuard.LockResult; -import org.onap.policy.guard.impl.PnfTargetLock; -import org.onap.policy.guard.impl.VmTargetLock; -import org.onap.policy.guard.impl.VnfTargetLock; - -public class PolicyGuardTest { - private static final String INSTANCENAME = "targetInstance"; - private static final int LOCK_SEC = 10; - - private static Factory saveFactory; - - private Factory factory; - private PolicyResourceLockManager mgr; - private UUID uuid; - private DummyLockCallback dlcb; - - private class DummyLockCallback implements LockCallback { - @Override - public boolean isActive() { - return false; - } - - @Override - public boolean releaseLock() { - return false; - } - } - - private class DummyTargetLock implements TargetLock { - private TargetType type; - private UUID reqid; - - public DummyTargetLock(TargetType type, UUID reqid) { - this.type = type; - this.reqid = reqid; - } - - @Override - public UUID getLockId() { - return null; - } - - @Override - public TargetType getTargetType() { - return type; - } - - @Override - public String getTargetInstance() { - return INSTANCENAME; - } - - @Override - public UUID getRequestId() { - return reqid; - } - } - - @BeforeClass - public static void setUpBeforeClass() { - saveFactory = PolicyGuard.getFactory(); - } - - @AfterClass - public static void tearDownAfterClass() { - PolicyGuard.setFactory(saveFactory); - } - - /** - * Setup method. - */ - @Before - public void setUp() { - mgr = spy(new PolicyResourceLockManager() { - /* - * we want each test to have its own lock manager, but the constructor for the - * manager is protected; this gets around that - */ - }); - - factory = mock(Factory.class); - when(factory.getManager()).thenReturn(mgr); - - uuid = UUID.randomUUID(); - dlcb = new DummyLockCallback(); - - PolicyGuard.setFactory(factory); - } - - @Test - public void testLockVm() { - TargetType type = TargetType.VM; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VmTargetLock.class, result.getB().getClass()); - - VmTargetLock vtl = (VmTargetLock) result.getB(); - assertNotNull(vtl.getLockId()); - assertEquals(INSTANCENAME, vtl.getTargetInstance()); - assertEquals(TargetType.VM, vtl.getTargetType()); - assertNotNull(vtl.getRequestId()); - assertEquals(dlcb, vtl.getCallback()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - @Test - public void testLockPnf() { - TargetType type = TargetType.PNF; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(PnfTargetLock.class, result.getB().getClass()); - - PnfTargetLock ptl = (PnfTargetLock) result.getB(); - assertNotNull(ptl.getLockId()); - assertEquals(INSTANCENAME, ptl.getTargetInstance()); - assertEquals(TargetType.PNF, ptl.getTargetType()); - assertNotNull(ptl.getRequestId()); - assertEquals(dlcb, ptl.getCallback()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - - @Test - public void testLockVnf() { - TargetType type = TargetType.VNF; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VnfTargetLock.class, result.getB().getClass()); - - VnfTargetLock vtl = (VnfTargetLock) result.getB(); - assertNotNull(vtl.getLockId()); - assertEquals(INSTANCENAME, vtl.getTargetInstance()); - assertEquals(TargetType.VNF, vtl.getTargetType()); - assertNotNull(vtl.getRequestId()); - assertEquals(dlcb, vtl.getCallback()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - @Test - public void testLockVfc() { - TargetType type = TargetType.VFC; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_EXCEPTION, result.getA()); - assertNull(result.getB()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - @Test - public void testUnLockNotLocked() { - TargetType type = TargetType.VM; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VmTargetLock.class, result.getB().getClass()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - // Test unlock after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - @Test - public void testLockAlreadyLocked() { - TargetType type = TargetType.VM; - - // Test isLocked before and after lock added - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - LockResult result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VmTargetLock.class, result.getB().getClass()); - - UUID uuid2 = UUID.randomUUID(); - result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid2, dlcb, LOCK_SEC); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid2)); - - assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - - assertEquals(GuardResult.LOCK_DENIED, result.getA()); - assertNull(result.getB()); - - // Test isLocked after lock removed - PolicyGuard.unlockTarget(new DummyTargetLock(type, uuid)); - assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - } - - @Test - public void testInnards() { - TargetType type = TargetType.VM; - - assertFalse(dlcb.isActive()); - assertFalse(dlcb.releaseLock()); - - DummyTargetLock dtl = new DummyTargetLock(type, uuid); - assertNull(dtl.getLockId()); - assertEquals(uuid, dtl.getRequestId()); - assertEquals(INSTANCENAME, dtl.getTargetInstance()); - assertEquals(type, dtl.getTargetType()); - } - - @Test - public void testLockTargetTargetTypeStringUuidLockCallbackInt() { - TargetType type = TargetType.VM; - - LockResult result; - - // acquired - result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - verify(mgr).lock(INSTANCENAME, type + ":" + uuid, LOCK_SEC); - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VmTargetLock.class, result.getB().getClass()); - - // diff owner - denied - UUID uuid2 = UUID.randomUUID(); - result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid2, dlcb, LOCK_SEC + 10); - verify(mgr).lock(INSTANCENAME, type + ":" + uuid2, LOCK_SEC + 10); - assertEquals(GuardResult.LOCK_DENIED, result.getA()); - assertNull(result.getB()); - } - - @Test - public void testLockTargetTargetLockInt() { - TargetType type = TargetType.VM; - - LockResult result; - - // acquired - result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid, dlcb, LOCK_SEC); - verify(mgr).lock(INSTANCENAME, type + ":" + uuid, LOCK_SEC); - assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); - assertEquals(VmTargetLock.class, result.getB().getClass()); - - TargetLock lock = result.getB(); - - // refresh - re-acquired - assertEquals(GuardResult.LOCK_ACQUIRED, PolicyGuard.lockTarget(lock, LOCK_SEC + 1)); - verify(mgr).refresh(INSTANCENAME, type + ":" + uuid, LOCK_SEC + 1); - - // unlock - PolicyGuard.unlockTarget(lock); - - // refresh - denied, as we no longer own the lock - assertEquals(GuardResult.LOCK_DENIED, PolicyGuard.lockTarget(lock, LOCK_SEC + 2)); - } - - @Test(expected = IllegalArgumentException.class) - public void testMakeOwner_NullTargetType() { - PolicyGuard.isLocked(null, INSTANCENAME, uuid); - } - - @Test(expected = IllegalArgumentException.class) - public void testMakeOwner_NullReqId() { - PolicyGuard.isLocked(TargetType.PNF, INSTANCENAME, null); - } -} diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index 4cbdd49e5..cfd1877b1 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -8,9 +8,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,6 +34,7 @@ import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NewEventStatus; import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager; +import org.onap.policy.controlloop.eventmanager.LockCallbackWorkingMemory; import org.onap.policy.controlloop.actor.so.SoActorServiceProvider; import org.onap.policy.controlloop.actor.cds.CdsActorServiceProvider; import org.onap.policy.controlloop.actor.cds.CdsActorServiceProvider.CdsActorServiceManager; @@ -51,6 +52,7 @@ import org.onap.policy.appclcm.LcmCommonHeader; import org.onap.policy.cds.CdsResponse; import org.onap.policy.cds.client.CdsProcessorGrpcClient; import org.onap.policy.cds.properties.CdsServerProperties; +import org.onap.policy.drools.utils.Pair; import org.onap.policy.sdnr.PciRequestWrapper; import org.onap.policy.sdnr.PciResponseWrapper; import org.onap.policy.sdnr.PciRequest; @@ -64,10 +66,7 @@ import org.onap.policy.so.SoResponseWrapper; import org.onap.policy.sdnc.SdncRequest; import org.onap.policy.sdnc.SdncManager; import org.onap.policy.sdnc.SdncResponse; -import org.onap.policy.guard.PolicyGuard; -import org.onap.policy.guard.PolicyGuard.LockResult; -import org.onap.policy.guard.TargetLock; -import org.onap.policy.guard.GuardResult; +import org.onap.policy.drools.core.lock.Lock; import org.onap.policy.guard.PolicyGuardRequest; import org.onap.policy.guard.PolicyGuardResponse; import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes; @@ -144,24 +143,24 @@ end rule "${policyName}.SETUP" salience 1 when - not( Params( getClosedLoopControlName() == "${closedLoopControlName}", + not( Params( getClosedLoopControlName() == "${closedLoopControlName}", getControlLoopYaml() == "${controlLoopYaml}" ) ) then - + Params params = new Params(); params.setClosedLoopControlName("${closedLoopControlName}"); params.setControlLoopYaml("${controlLoopYaml}"); insert(params); - + ParamsInitCleaner initCleaner = new ParamsInitCleaner(); initCleaner.setClosedLoopControlName("${closedLoopControlName}"); insert(initCleaner); // Note: globals have bad behavior when persistence is used, // hence explicitly getting the logger vs using a global - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {} : YAML=[{}]", params.getClosedLoopControlName(), drools.getRule().getName(), + logger.info("{}: {} : YAML=[{}]", params.getClosedLoopControlName(), drools.getRule().getName(), params.getControlLoopYaml()); end @@ -175,15 +174,15 @@ rule "${policyName}.EVENT" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + not ( ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - + try { - + // // Check the event, because we need it to not be null when // we create the ControlLoopEventManager. The ControlLoopEventManager @@ -197,12 +196,12 @@ rule "${policyName}.EVENT" notification.setPolicyName(drools.getRule().getName()); notification.setPolicyScope("${policyScope}"); notification.setPolicyVersion("${policyVersion}"); - + // // Let interested parties know // PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); - + // // Retract it from memory // @@ -213,10 +212,10 @@ rule "${policyName}.EVENT" // // Create an EventManager // - ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), + ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.getRequestId()); // - // Determine if EventManager can actively process the event + // Determine if EventManager can actively process the event // (i.e. syntax, is_closed_loop_disabled checks etc.) // VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event); @@ -258,7 +257,7 @@ rule "${policyName}.EVENT" // retract($event); } - + // // Now that the manager is inserted into Drools working memory, we'll wait for // another rule to fire in order to continue processing. This way we can also @@ -267,7 +266,7 @@ rule "${policyName}.EVENT" } } catch (Exception e) { logger.warn("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName(), e); - + VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.REJECTED); notification.setMessage("Exception occurred: " + e.getMessage()); @@ -295,17 +294,17 @@ rule "${policyName}.EVENT.MANAGER" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "ClosedLoop", !expired ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} clTimer={}", + logger.info("{}: {}: event={} manager={} clTimer={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $event, $manager, $clTimer); - + try { // // Check which event this is. @@ -318,7 +317,7 @@ rule "${policyName}.EVENT.MANAGER" // // We don't care about subsequent onsets // - logger.info("{}: {}: subsequent onset", + logger.info("{}: {}: subsequent onset", $params.getClosedLoopControlName(), drools.getRule().getName()); retract($event); return; @@ -327,7 +326,7 @@ rule "${policyName}.EVENT.MANAGER" // // Ignore any bad syntax events // - logger.warn("{}: {}: syntax error", + logger.warn("{}: {}: syntax error", $params.getClosedLoopControlName(), drools.getRule().getName()); retract($event); return; @@ -338,12 +337,12 @@ rule "${policyName}.EVENT.MANAGER" // cleanup and avoid the other rules being fired for this event. // if (eventStatus != NewEventStatus.FIRST_ONSET) { - logger.warn("{}: {}: not first onset", + logger.warn("{}: {}: not first onset", $params.getClosedLoopControlName(), drools.getRule().getName()); retract($event); } - - logger.debug("{}: {}: target={}", $params.getClosedLoopControlName(), + + logger.debug("{}: {}: target={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $event.getTarget()); // // Now start seeing if we need to process this event @@ -353,20 +352,20 @@ rule "${policyName}.EVENT.MANAGER" // Check if this is a Final Event // VirtualControlLoopNotification notification = $manager.isControlLoopFinal(); - - + + if (notification != null) { // // Its final, but are we waiting for abatement? // if ($manager.getNumAbatements() > 0) { - logger.info("{}: {}: abatement received for {}. Closing the control loop", - $params.getClosedLoopControlName(), drools.getRule().getName(), + logger.info("{}: {}: abatement received for {}. Closing the control loop", + $params.getClosedLoopControlName(), drools.getRule().getName(), $event.getRequestId()); - + /// DB Write---end event processing for this RequestId() $manager.commitAbatement("Event Abated","Closed"); - + notification.setFrom("policy"); notification.setPolicyName(drools.getRule().getName()); notification.setPolicyScope("${policyScope}"); @@ -378,22 +377,22 @@ rule "${policyName}.EVENT.MANAGER" // // Unlock the target // - TargetLock lock = $manager.unlockCurrentOperation(); - if (lock != null) { - logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(), - drools.getRule().getName(), lock); + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + logger.debug("{}: {}: retracting lock={}", $params.getClosedLoopControlName(), + drools.getRule().getName(), lock); retract(lock); } // // Retract everything from memory // - logger.info("{}: {}: retracting onset, manager, and timer", + logger.info("{}: {}: retracting onset, manager, and timer", $params.getClosedLoopControlName(), drools.getRule().getName()); - + retract($manager.getOnsetEvent()); - + // don't retract manager, etc. - a clean-up rule will do that - + // // TODO - what if we get subsequent Events for this RequestId? // By default, it will all start over again. May be confusing for Ruby. @@ -404,18 +403,18 @@ rule "${policyName}.EVENT.MANAGER" // Check whether we need to wait for abatement // if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.getNotification() == ControlLoopNotificationType.FINAL_SUCCESS) { - logger.info("{}: {}: waiting for abatement ..", + logger.info("{}: {}: waiting for abatement ..", $params.getClosedLoopControlName(), drools.getRule().getName()); } else { - logger.info("{}: {}: no abatement expect for {}. Closing the control loop", - $params.getClosedLoopControlName(), drools.getRule().getName(), + logger.info("{}: {}: no abatement expect for {}. Closing the control loop", + $params.getClosedLoopControlName(), drools.getRule().getName(), $event.getRequestId()); - + notification.setFrom("policy"); notification.setPolicyName(drools.getRule().getName()); notification.setPolicyScope("${policyScope}"); notification.setPolicyVersion("${policyVersion}"); - + // // In this case, we are done // @@ -423,20 +422,20 @@ rule "${policyName}.EVENT.MANAGER" // // Unlock the target // - TargetLock lock = $manager.unlockCurrentOperation(); - if (lock != null) { - logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(), + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + logger.debug("{}: {}: retracting lock={}", $params.getClosedLoopControlName(), drools.getRule().getName(), lock); retract(lock); } // // Retract everything from memory // - logger.info("{}: {}: retracting onset, manager, and timer", + logger.info("{}: {}: retracting onset, manager, and timer", $params.getClosedLoopControlName(), drools.getRule().getName()); - + retract($manager.getOnsetEvent()); - + // don't retract manager, etc. - a clean-up rule will do that } } @@ -449,66 +448,49 @@ rule "${policyName}.EVENT.MANAGER" // // Let's ask for a lock right away // - LockResult result = $manager.lockCurrentOperation(); - logger.info("{}: {}: guard lock acquired={}", - $params.getClosedLoopControlName(), drools.getRule().getName(), - result.getB()); - if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) { - // - // insert the operation into memory - // - insert(operation); - // - // insert operation timeout object - // - ControlLoopTimer opTimer = new ControlLoopTimer(); - opTimer.setTimerType("Operation"); - opTimer.setClosedLoopControlName($event.getClosedLoopControlName()); - opTimer.setRequestId($event.getRequestId().toString()); - Integer timeout = operation.getOperationTimeout(); - opTimer.setDelay(timeout > 0 ? timeout.toString() + "s" : $clTimer.getDelay()); - insert(opTimer); - - // - // Insert lock into memory - // - insert(result.getB()); - } else { - logger.debug("The target resource {} is already processing", - $event.getAai().get($event.getTarget())); - notification = new VirtualControlLoopNotification($event); - notification.setNotification(ControlLoopNotificationType.REJECTED); - notification.setMessage("The target " + $event.getAai().get($event.getTarget()) - + " is already locked"); - notification.setFrom("policy"); - notification.setPolicyName(drools.getRule().getName()); - notification.setPolicyScope("${policyScope}"); - notification.setPolicyVersion("${policyVersion}"); - - PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); + logger.info("{}: {}: requesting lock for operation={}", + $params.getClosedLoopControlName(), drools.getRule().getName(), + operation); + + Pair oldNew = $manager.lockCurrentOperation( + new LockCallbackWorkingMemory($params.getClosedLoopControlName(), drools.getWorkingMemory())); + if(oldNew.first() != null) { + logger.debug("{}: {}: retracting lock={}", $params.getClosedLoopControlName(), + drools.getRule().getName(), oldNew.first()); + retract(oldNew.first()); + } + if(oldNew.second() != null) { + logger.debug("{}: {}: inserting lock={}", $params.getClosedLoopControlName(), + drools.getRule().getName(), oldNew.second()); + insert(oldNew.second()); + } - retract($event); - - // don't retract manager, etc. - a clean-up rule will do that + // + // insert the operation into memory + // + insert(operation); + // + // insert operation timeout object + // + ControlLoopTimer opTimer = new ControlLoopTimer(); + opTimer.setTimerType("Operation"); + opTimer.setClosedLoopControlName($event.getClosedLoopControlName()); + opTimer.setRequestId($event.getRequestId().toString()); + Integer timeout = operation.getOperationTimeout(); + opTimer.setDelay(timeout > 0 ? timeout.toString() + "s" : $clTimer.getDelay()); + insert(opTimer); - if (result.getB() != null) { - retract(result.getB()); - } - } - logger.info("{}: {}: starting operation={}", - $params.getClosedLoopControlName(), drools.getRule().getName(), - operation); } else { // // Probably waiting for abatement // - logger.info("{}: {}: no operation, probably waiting for abatement", + logger.info("{}: {}: no operation, probably waiting for abatement", $params.getClosedLoopControlName(), drools.getRule().getName()); } } } catch (Exception e) { - logger.warn("{}: {}: unexpected", - $params.getClosedLoopControlName(), + logger.warn("{}: {}: unexpected", + $params.getClosedLoopControlName(), drools.getRule().getName(), e); VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); @@ -518,14 +500,53 @@ rule "${policyName}.EVENT.MANAGER" notification.setPolicyName(drools.getRule().getName()); notification.setPolicyScope("${policyScope}"); notification.setPolicyVersion("${policyVersion}"); - + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); retract($event); - + // don't retract manager, etc. - a clean-up rule will do that } - + +end + +/* +* +* Lock denied +* +*/ +rule "${policyName}.EVENT.MANAGER.OPERATION.LOCK.DENIED" + when + $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + requestId == $event.getRequestId() ) + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + onset.getRequestId() == $event.getRequestId(), "None".equalsIgnoreCase(getGuardApprovalStatus()) ) + $lock : Lock (ownerKey == $event.getRequestId().toString(), isUnavailable()) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}: event={} manager={} operation={} lock={}", + $params.getClosedLoopControlName(), drools.getRule().getName(), + $event, $manager, $operation, $lock); + + logger.debug("The target resource {} is already processing", + $event.getAai().get($event.getTarget())); + VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); + notification.setNotification(ControlLoopNotificationType.REJECTED); + notification.setMessage("The target " + $event.getAai().get($event.getTarget()) + + " is already locked"); + notification.setFrom("policy"); + notification.setPolicyName(drools.getRule().getName()); + notification.setPolicyScope("${policyScope}"); + notification.setPolicyVersion("${policyVersion}"); + + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); + + retract($event); + + // don't retract manager, etc. - a clean-up rule will do that end /* @@ -537,28 +558,27 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId(), "Permit".equalsIgnoreCase(getGuardApprovalStatus()) ) - $lock : TargetLock (requestId == $event.getRequestId()) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} operation={} lock={}", + logger.info("{}: {}: event={} manager={} operation={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock); + $event, $manager, $operation); Object request = null; boolean caughtException = false; - + try { request = $operation.startOperation($event); - + if (request != null) { - logger.debug("{}: {}: starting operation ..", + logger.debug("{}: {}: starting operation ..", $params.getClosedLoopControlName(), drools.getRule().getName()); // // Tell interested parties we are performing this Operation @@ -585,19 +605,19 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" } break; case "SO": - // at this point the AAI named query request should have already been made, + // at this point the AAI named query request should have already been made, // the response recieved and used // in the construction of the SO Request which is stored in operationRequest if(request instanceof SoRequest) { - // Call SO. The response will be inserted into memory once it's received + // Call SO. The response will be inserted into memory once it's received class mySoCallback implements SoManager.SoCallback { public void onSoResponseWrapper(SoResponseWrapper wrapper) { drools.getWorkingMemory().insert(wrapper); } } - SoActorServiceProvider.sendRequest($event.getRequestId().toString(), - new mySoCallback(), + SoActorServiceProvider.sendRequest($event.getRequestId().toString(), + new mySoCallback(), request, PolicyEngineConstants.getManager().getEnvironmentProperty("so.url"), PolicyEngineConstants.getManager().getEnvironmentProperty("so.username"), @@ -608,7 +628,7 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" if (request instanceof VfcRequest) { // Start VFC thread class myVfcCallback implements VfcManager.VfcCallback { - + public void onResponse(VfcResponse responseError) { drools.getWorkingMemory().insert(responseError); } @@ -620,9 +640,9 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" PolicyEngineConstants.getManager().getEnvironmentProperty("vfc.username"), PolicyEngineConstants.getManager().getEnvironmentProperty("vfc.password"))); t.start(); - } + } break; - + case "SDNC": if (request instanceof SdncRequest) { // Start SDNC thread @@ -630,16 +650,16 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" public void onCallback(SdncResponse response) { drools.getWorkingMemory().insert(response); } - } + } // Start SDNC thread - Thread t = new Thread(new SdncManager(new mySdncCallback(), + Thread t = new Thread(new SdncManager(new mySdncCallback(), (SdncRequest)request, PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.url"), PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.username"), PolicyEngineConstants.getManager().getEnvironmentProperty("sdnc.password"))); t.start(); } - break; + break; case "SDNR": if (request instanceof PciRequestWrapper) { PolicyEngineConstants.getManager().deliver("SDNR-CL", request); @@ -678,8 +698,8 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" // // What happens if its null? // - logger.warn("{}: {}: unexpected null operation request", - $params.getClosedLoopControlName(), + logger.warn("{}: {}: unexpected null operation request", + $params.getClosedLoopControlName(), drools.getRule().getName()); if ("SO".equals($operation.policy.getActor())) { retract($opTimer); @@ -697,14 +717,14 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" modify($manager) {finishOperation($operation)}; } } - + } catch (Exception e) { String msg = e.getMessage(); - logger.warn("{}: {}: operation={}: AAI failure: {}", + logger.warn("{}: {}: operation={}: AAI failure: {}", $params.getClosedLoopControlName(), drools.getRule().getName(), $operation, msg, e); $operation.setOperationHasException(msg); - + if(request != null) { // // Create a notification for it ("DB Write - end operation") @@ -717,15 +737,15 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE); notification.setMessage($operation.getOperationHistory()); notification.setHistory($operation.getHistory()); - + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); } - + retract($opTimer); retract($operation); caughtException = true; } - + // Having the modify statement in the catch clause doesn't work for whatever reason if (caughtException) { modify($manager) {finishOperation($operation)}; @@ -735,7 +755,7 @@ end /* * -* We were able to acquire a lock so now let's ask Xacml Guard whether +* We were able to acquire a lock so now let's ask Xacml Guard whether * we are allowed to proceed with the request to the actor. * */ @@ -743,24 +763,24 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), - onset.getRequestId() == $event.getRequestId(), getGuardApprovalStatus() == "NONE" ) - $lock : TargetLock (requestId == $event.getRequestId()) + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + onset.getRequestId() == $event.getRequestId(), "None".equalsIgnoreCase(getGuardApprovalStatus()) ) + $lock : Lock (ownerKey == $event.getRequestId().toString(), isActive()) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} operation={} lock={}", + logger.info("{}: {}: event={} manager={} operation={} lock={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $event, $manager, $operation, $lock); - + // // Sending notification that we are about to query Guard ("DB write - start operation") // VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.OPERATION); - notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " " + notification.setMessage("Sending guard query for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe()); notification.setHistory($operation.getHistory()); notification.setFrom("policy"); @@ -771,11 +791,11 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED" PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); // - // Now send Guard Request to XACML Guard. In order to bypass the call to Guard, + // Now send Guard Request to XACML Guard. In order to bypass the call to Guard, // just change guardEnabled to false. // - // In order to use REST XACML, provide a URL instead of "" as a second argument - // to the CallGuardTask() and set the first argument to null + // In order to use REST XACML, provide a URL instead of "" as a second argument + // to the CallGuardTask() and set the first argument to null // (instead of XacmlPdpEngine). // @@ -822,35 +842,34 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED" end // -// This rule will be triggered when a thread talking to the XACML Guard inserts a +// This rule will be triggered when a thread talking to the XACML Guard inserts a // guardResponse object into the working memory // rule "${policyName}.GUARD.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), - requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + requestId == $event.getRequestId() ) + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $lock : TargetLock (requestId == $event.getRequestId()) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) $guardResponse : PolicyGuardResponse(requestId == $event.getRequestId(), $operation.policy.recipe == operation) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}", + logger.info("{}: {}: event={} manager={} operation={} opTimer={} guardResponse={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $opTimer, $guardResponse); - - + $event, $manager, $operation, $opTimer, $guardResponse); + + //we will permit the operation if there was no Guard for it if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){ $guardResponse.setResult("Permit"); } - + // // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny") // @@ -863,11 +882,11 @@ rule "${policyName}.GUARD.RESPONSE" notification.setPolicyName(drools.getRule().getName()); notification.setPolicyScope("${policyScope}"); notification.setPolicyVersion("${policyVersion}"); - + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); - + if("Permit".equalsIgnoreCase($guardResponse.getResult())){ - + modify($operation){setGuardApprovalStatus($guardResponse.getResult())}; } else { @@ -878,9 +897,9 @@ rule "${policyName}.GUARD.RESPONSE" retract($operation); modify($manager) {finishOperation($operation)}; } - + retract($guardResponse); - + end /* @@ -897,29 +916,28 @@ end rule "${policyName}.APPC.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), - closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + closedLoopEventStatus == ControlLoopEventStatus.ONSET ) + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : Response( getCommonHeader().RequestId == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $opTimer, $response); + $event, $manager, $operation, $opTimer, $response); // // Get the result of the operation // PolicyResult policyResult = $operation.onResponse($response); if (policyResult != null) { - logger.debug("{}: {}: operation finished - result={}", + logger.debug("{}: {}: operation finished - result={}", $params.getClosedLoopControlName(), drools.getRule().getName(), policyResult); // @@ -993,14 +1011,14 @@ rule "${policyName}.APPC.RESPONSE.CLEANUP" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $response : Response($id : getCommonHeader().RequestId ) - not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) + not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: orphan appc response={}", + logger.debug("{}: {}: orphan appc response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $id); - + // // Retract it // @@ -1015,33 +1033,32 @@ end rule "${policyName}.APPC.LCM.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), - closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + closedLoopEventStatus == ControlLoopEventStatus.ONSET ) + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : LcmResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); - + $event, $manager, $operation, $operation, $opTimer, $response); + // // Get the result of the operation // PolicyResult policyResult = $operation.onResponse($response); if (policyResult != null) { - logger.debug("{}: {}: operation finished - result={}", + logger.debug("{}: {}: operation finished - result={}", $params.getClosedLoopControlName(), drools.getRule().getName(), policyResult); - + // // This Operation has completed, construct a notification showing our results. (DB write - end operation) // @@ -1103,12 +1120,12 @@ rule "${policyName}.APPC.LCM.RESPONSE.CLEANUP" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $response : LcmResponseWrapper($id : getBody().getCommonHeader().getRequestId ) - not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) + not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: orphan appc response={}", + logger.debug("{}: {}: orphan appc response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $id); // // Retract it @@ -1124,33 +1141,32 @@ end rule "${policyName}.SDNR.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), - closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + closedLoopEventStatus == ControlLoopEventStatus.ONSET ) + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : PciResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.getRequestId() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); - + $event, $manager, $operation, $operation, $opTimer, $response); + // // Get the result of the operation // PolicyResult policyResult = $operation.onResponse($response); if (policyResult != null) { - logger.debug("{}: {}: operation finished - result={}", + logger.debug("{}: {}: operation finished - result={}", $params.getClosedLoopControlName(), drools.getRule().getName(), policyResult); - + // // This Operation has completed, construct a notification showing our results. (DB write - end operation) // @@ -1212,12 +1228,12 @@ rule "${policyName}.SDNR.RESPONSE.CLEANUP" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $response : PciResponseWrapper($id : getBody().getCommonHeader().getRequestId ) - not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) + not ( VirtualControlLoopEvent( requestId == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: orphan SDNR response={}", + logger.debug("{}: {}: orphan SDNR response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $id); // // Retract it @@ -1233,32 +1249,31 @@ end rule "${policyName}.SO.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : SoResponseWrapper(requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); - + $event, $manager, $operation, $operation, $opTimer, $response); + // Get the result of the operation // PolicyResult policyResult = $operation.onResponse($response); if (policyResult != null) { - logger.debug("{}: {}: operation finished - result={}", + logger.debug("{}: {}: operation finished - result={}", $params.getClosedLoopControlName(), drools.getRule().getName(), policyResult); - + // // This Operation has completed, construct a notification showing our results // @@ -1321,22 +1336,21 @@ end rule "${policyName}.VFC.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) - $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() ) + $response : VfcResponse( requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation // @@ -1398,22 +1412,21 @@ end rule "${policyName}.SDNC.RESPONSE" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) - $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), + $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) - $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() ) + $response : SdncResponse( requestId.toString() == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation // @@ -1481,16 +1494,15 @@ rule "${policyName}.CDS.RESPONSE" onset.getRequestId() == $event.getRequestId() ) $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), timerType == "Operation", !expired ) - $lock : TargetLock (requestId == $event.getRequestId()) $response : CdsResponse( requestId == $event.getRequestId().toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={} response={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer, $response); + $event, $manager, $operation, $operation, $opTimer, $response); // Get the result of the operation PolicyResult policyResult = $operation.onResponse($response); @@ -1571,23 +1583,22 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), + $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.getClosedLoopControlName(), onset.getRequestId() == $event.getRequestId() ) - $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $opTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), expired, timerType == "Operation" ) - $lock : TargetLock (requestId == $event.getRequestId()) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}", + logger.debug("{}: {}: event={} manager={} operation={} opTimer={}", $params.getClosedLoopControlName(), drools.getRule().getName(), - $event, $manager, $operation, $lock, $operation, $opTimer); - + $event, $manager, $operation, $operation, $opTimer); + // - // Tell it its timed out + // Tell it it has timed out // $operation.setOperationHasTimedOut(); // @@ -1638,16 +1649,16 @@ rule "${policyName}.EVENT.MANAGER.TIMEOUT" when $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" ) $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() ) - $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), + $manager : ControlLoopEventManager( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId() ) - $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), + $clTimer : ControlLoopTimer( closedLoopControlName == $event.getClosedLoopControlName(), requestId == $event.getRequestId().toString(), expired, timerType == "ClosedLoop" ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName()); - logger.debug("{}: {}: event={}", + logger.debug("{}: {}: event={}", $params.getClosedLoopControlName(), drools.getRule().getName(), $event); // @@ -1680,47 +1691,46 @@ rule "${policyName}.EVENT.MANAGER.CLEANUP" when $manager : ControlLoopEventManager( $clName : getClosedLoopControlName(), $requestId : getRequestId() ) $operations : LinkedList() - from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName, + from collect( ControlLoopOperationManager( onset.closedLoopControlName == $clName, onset.getRequestId() == $requestId ) ) $timers : LinkedList() - from collect( ControlLoopTimer( closedLoopControlName == $clName, + from collect( ControlLoopTimer( closedLoopControlName == $clName, requestId == $requestId.toString() ) ) - $locks : LinkedList() - from collect( TargetLock (requestId == $requestId) ) not( VirtualControlLoopEvent( closedLoopControlName == $clName, requestId == $requestId ) ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, drools.getRule().getName()); - logger.debug("{}: {}: manager={} timers={} operations={}", + logger.debug("{}: {}: manager={} timers={} operations={}", $clName, drools.getRule().getName(), $manager, $timers.size(), $operations.size()); - + + // + // Retract lock by invoking unlock() + // + Lock lock = $manager.unlockCurrentOperation(); + if(lock != null) { + retract(lock); + } + // // Retract EVERYTHING // + retract($manager); - + for(Object manager: $operations) { retract((ControlLoopOperationManager) manager); } for(Object timer: $timers) { retract((ControlLoopTimer) timer); } - for(Object lock: $locks) { - TargetLock tgt = (TargetLock) lock; - // - // Ensure we release the lock - // - PolicyGuard.unlockTarget(tgt); - retract(tgt); - } end /* * -* This rule will clean up any rogue onsets where there is no +* This rule will clean up any rogue onsets where there is no * ControlLoopParams object corresponding to the onset event. * */ @@ -1729,10 +1739,10 @@ rule "${policyName}.EVENT.CLEANUP" $event : VirtualControlLoopEvent( $clName: closedLoopControlName ) not ( Params( getClosedLoopControlName() == $clName) ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $clName, drools.getRule().getName()); - logger.debug("{}: {}: orphan onset event={}", + logger.debug("{}: {}: orphan onset event={}", $clName, drools.getRule().getName(), $event); retract($event); @@ -1748,11 +1758,11 @@ rule "${policyName}.PARAMS.CLEANING" $params: Params( ) ParamsInitCleaner( ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), drools.getRule().getName(), $params.getControlLoopYaml()); - + ParamsCleaner cleaner = new ParamsCleaner(); cleaner.setClosedLoopControlName($params.getClosedLoopControlName()); cleaner.setControlLoopYaml($params.getControlLoopYaml()); @@ -1768,10 +1778,10 @@ rule "${policyName}.PARAMS.FINISHED" when $initCleaner: ParamsInitCleaner( ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {}", $initCleaner.getClosedLoopControlName(), drools.getRule().getName()); - + retract($initCleaner); end @@ -1788,11 +1798,11 @@ rule "${policyName}.PARAMS.ACTIVE" $cleaner: ParamsCleaner( getClosedLoopControlName() == "${closedLoopControlName}", getControlLoopYaml() == "${controlLoopYaml}" ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), drools.getRule().getName(), $params.getControlLoopYaml()); - + retract($cleaner); end @@ -1808,11 +1818,11 @@ rule "${policyName}.PARAMS.DELETE" $cleaner: ParamsCleaner( getClosedLoopControlName() == $params.getClosedLoopControlName(), getControlLoopYaml() == $params.getControlLoopYaml() ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), drools.getRule().getName(), $params.getControlLoopYaml()); - + retract($params); end @@ -1825,10 +1835,10 @@ rule "${policyName}.PARAMS.CLEANED" when $cleaner: ParamsCleaner( ) then - + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); logger.info("{}: {} : YAML=[{}]", $cleaner.getClosedLoopControlName(), drools.getRule().getName(), $cleaner.getControlLoopYaml()); - + retract($cleaner); end diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/ControlLoopFailureTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/ControlLoopFailureTest.java index 0793b8825..db5da1e4a 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/ControlLoopFailureTest.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/ControlLoopFailureTest.java @@ -48,6 +48,8 @@ public class ControlLoopFailureTest extends ControlLoopBase implements TopicList private UUID requestId2; private UUID requestId3; private int eventCount; + private int nsuccess = 0; + private int nreject = 0; /** * Setup simulator. @@ -106,19 +108,25 @@ public class ControlLoopFailureTest extends ControlLoopBase implements TopicList sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, "vnf01"); /* - * Send a second event requesting an action for a different target entity + * Send a second event for a different target to ensure there are no problems with obtaining + * a lock */ sendEvent(pair.first, requestId2, ControlLoopEventStatus.ONSET, "vnf02"); /* - * Send a second event for a different target to ensure there are no problems with obtaining - * a lock for a different + * Send a third event requesting an action for a duplicate target entity */ + sendEvent(pair.first, requestId3, ControlLoopEventStatus.ONSET, "vnf01"); + kieSession.fireUntilHalt(); // allow object clean-up kieSession.fireAllRules(); + // should be one success and one failure for vnf01 + assertEquals(1, nsuccess); + assertEquals(1, nreject); + /* * The only fact in memory should be Params */ @@ -136,7 +144,7 @@ public class ControlLoopFailureTest extends ControlLoopBase implements TopicList * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) */ @Override - public void onTopicEvent(CommInfrastructure commType, String topic, String event) { + public synchronized void onTopicEvent(CommInfrastructure commType, String topic, String event) { /* * Pull the object that was sent out to DMAAP and make sure it is a ControlLoopNoticiation * of type active @@ -156,6 +164,17 @@ public class ControlLoopFailureTest extends ControlLoopBase implements TopicList if (policyName.endsWith("EVENT")) { logger.debug("Rule Fired: " + notification.getPolicyName()); assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.getNotification())); + } else if (policyName.endsWith("DENIED")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.REJECTED.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().contains("is already locked")); + if (requestId.equals(notification.getRequestId()) || requestId3.equals(notification.getRequestId())) { + ++nreject; + } + if (++eventCount == 3) { + kieSession.halt(); + } } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { logger.debug("Rule Fired: " + notification.getPolicyName()); assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); @@ -181,18 +200,16 @@ public class ControlLoopFailureTest extends ControlLoopBase implements TopicList assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.getNotification())); assertNotNull(notification.getMessage()); assertTrue(notification.getMessage().startsWith("actor=APPC")); - if (requestId.equals(notification.getRequestId())) { - sendEvent(pair.first, requestId, ControlLoopEventStatus.ABATED, "vnf01"); + if (requestId.equals(notification.getRequestId()) || requestId3.equals(notification.getRequestId())) { + sendEvent(pair.first, notification.getRequestId(), ControlLoopEventStatus.ABATED, "vnf01"); } else if (requestId2.equals(notification.getRequestId())) { sendEvent(pair.first, requestId2, ControlLoopEventStatus.ABATED, "vnf02"); } } else if (policyName.endsWith("EVENT.MANAGER")) { logger.debug("Rule Fired: " + notification.getPolicyName()); - if (requestId3.equals(notification.getRequestId())) { - /* - * The event with the duplicate target should be rejected - */ - assertTrue(ControlLoopNotificationType.REJECTED.equals(notification.getNotification())); + if (requestId.equals(notification.getRequestId()) || requestId3.equals(notification.getRequestId())) { + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.getNotification())); + ++nsuccess; } else { assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.getNotification())); } -- cgit 1.2.3-korg