From a1c8c6703a339b9c7aaffa85b9f62fc03117d80a Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 27 Apr 2018 09:54:17 -0400 Subject: Modify PolicyGuard to use new locking API Modified PolicyGuard to use the locking API from policy-core instead of its own internal map. Initialized PolicyGuard.factory. Fixed bug in eventmanager junit test uncovered due to changes to PolicyGuard. Change-Id: I853ee5f146f3bde16b3f6e65bc188ca7c0cc4f73 Issue-ID: POLICY-577 Signed-off-by: Jim Hahn --- .../java/org/onap/policy/guard/PolicyGuard.java | 187 +++++++++++++++------ 1 file changed, 131 insertions(+), 56 deletions(-) (limited to 'controlloop/common/guard/src/main') 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 index 47faa88c2..66a25ea63 100644 --- 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 @@ -20,11 +20,11 @@ package org.onap.policy.guard; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; - +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; 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; @@ -36,8 +36,12 @@ public class PolicyGuard { // Cannot instantiate this static class } - private static Map activeLocks = new HashMap<>(); 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; @@ -60,6 +64,21 @@ public class PolicyGuard { return parameterB; } } + + /** + * @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 + */ + protected static void setFactory(Factory factory) { + PolicyGuard.factory = factory; + } /** * Lock a target. @@ -69,50 +88,75 @@ public class PolicyGuard { * @param requestID the request Id * @param callback the LockCallback * @return the LockResult + * @throws IllegalArgumentException if an argument is null */ public static LockResult lockTarget(TargetType targetType, String targetInstance, UUID requestID, LockCallback callback) { + + String owner = makeOwner(targetType, requestID); + + GuardResult guardResult = managerLockTarget(targetInstance, owner); + if(guardResult != GuardResult.LOCK_ACQUIRED) { + return LockResult.createLockResult(guardResult, null); + } + + TargetLock lock = null; + switch (targetType) { + case PNF: + // + // Create the Lock object + // + lock = new PNFTargetLock(targetType, targetInstance, requestID, callback); + break; + case VM: + // + // Create the Lock object + // + lock = new VMTargetLock(targetType, targetInstance, requestID, callback); + break; + case VNF: + // + // Create the Lock object + // + lock = new VNFTargetLock(targetType, targetInstance, requestID, callback); + break; + + default: + logger.error("invalid target type {} for lock on {}", targetType, targetInstance); + factory.getManager().unlock(targetInstance, owner); + return LockResult.createLockResult(GuardResult.LOCK_EXCEPTION, null); + } + + // + // Return result + // + logger.debug("Locked {}", lock); + return LockResult.createLockResult(GuardResult.LOCK_ACQUIRED, lock); + } - synchronized (activeLocks) { - // - // Is there a lock on this instance already? - // - if (activeLocks.containsKey(targetInstance)) { - return LockResult.createLockResult(GuardResult.LOCK_DENIED, null); - } - TargetLock lock = null; - switch (targetType) { - case PNF: - // - // Create the Lock object - // - lock = new PNFTargetLock(targetType, targetInstance, requestID, callback); - break; - case VM: - // - // Create the Lock object - // - lock = new VMTargetLock(targetType, targetInstance, requestID, callback); - break; - case VNF: - // - // Create the Lock object - // - lock = new VNFTargetLock(targetType, targetInstance, requestID, callback); - break; - - default: - return LockResult.createLockResult(GuardResult.LOCK_EXCEPTION, null); - } - // - // Keep track of it - // - activeLocks.put(targetInstance, lock); - // - // Return result - // - logger.debug("Locking {}", lock); - return LockResult.createLockResult(GuardResult.LOCK_ACQUIRED, lock); + /** + * Asks the manager to lock the given target. + * @param targetInstance + * @param owner + * @return the result: acquired, denied, or exception + */ + private static GuardResult managerLockTarget(String targetInstance, String owner) { + try { + Future result = factory.getManager().lock(targetInstance, owner, null); + return(result.get() ? GuardResult.LOCK_ACQUIRED : GuardResult.LOCK_DENIED); + + } catch(IllegalStateException e) { + logger.warn("{} attempted to re-lock {}", owner, targetInstance); + return GuardResult.LOCK_DENIED; + + } catch (InterruptedException e) { + logger.error("exception getting lock for {}", targetInstance, e); + Thread.currentThread().interrupt(); + return GuardResult.LOCK_EXCEPTION; + + } catch (ExecutionException e) { + logger.error("exception getting lock for {}", targetInstance, e); + return GuardResult.LOCK_EXCEPTION; } } @@ -122,15 +166,18 @@ public class PolicyGuard { * @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) { - synchronized (activeLocks) { - if (activeLocks.containsKey(lock.getTargetInstance())) { - logger.debug("Unlocking {}", lock); - return (activeLocks.remove(lock.getTargetInstance()) != null); - } - return false; + 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; } /** @@ -140,14 +187,42 @@ public class PolicyGuard { * @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) { - synchronized (activeLocks) { - if (activeLocks.containsKey(targetInstance)) { - TargetLock lock = activeLocks.get(targetInstance); - return (lock.getTargetType().equals(targetType) && lock.getRequestID().equals(requestID)); - } - return false; + 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 + * @param requestID + * @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.toString() + ":" + requestID.toString(); + } + + /** + * Factory to access various objects. + */ + public static class Factory { + + /** + * @return the lock manager to be used + */ + public PolicyResourceLockManager getManager() { + return PolicyResourceLockManager.getInstance(); } } } -- cgit 1.2.3-korg