diff options
author | Jim Hahn <jrh3@att.com> | 2021-05-03 09:11:30 -0400 |
---|---|---|
committer | Jim Hahn <jrh3@att.com> | 2021-05-03 10:11:09 -0400 |
commit | cbdf437729ca4d010147acfb208ecd90ef65777c (patch) | |
tree | 1505d656c5c455b6a0f69d533244a86e8a0879d7 /controlloop/common/eventmanager/src/main | |
parent | 9496f31d3b2a1674f57a0395d050be0d9c6b87f0 (diff) |
Add releaseLock() method to event manager
Issue-ID: POLICY-3261
Change-Id: I28a5356ebfc4a6ea1792ef35bc603054208bf73b
Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'controlloop/common/eventmanager/src/main')
3 files changed, 72 insertions, 10 deletions
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ActorConstants.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ActorConstants.java index 2591a3fa0..26d5ab8bf 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ActorConstants.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ActorConstants.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 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. @@ -24,6 +24,7 @@ public class ActorConstants { public static final String CL_TIMEOUT_ACTOR = "-CL-TIMEOUT-"; public static final String LOCK_ACTOR = "LOCK"; public static final String LOCK_OPERATION = "Lock"; + public static final String UNLOCK_OPERATION = "Unlock"; public static final String PAYLOAD_KEY_VF_COUNT = "vfCount"; 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 248a41be6..2c7e133af 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2021 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. @@ -21,6 +21,7 @@ package org.onap.policy.controlloop.eventmanager; import java.io.Serializable; +import java.time.Instant; import java.util.Deque; import java.util.HashMap; import java.util.Map; @@ -37,8 +38,10 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.ToString; import org.onap.policy.controlloop.ControlLoopException; +import org.onap.policy.controlloop.ControlLoopOperation; import org.onap.policy.controlloop.actorserviceprovider.ActorService; import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; +import org.onap.policy.controlloop.actorserviceprovider.OperationResult; import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; import org.onap.policy.controlloop.ophistory.OperationHistoryDataManager; import org.onap.policy.controlloop.ophistory.OperationHistoryDataManagerStub; @@ -189,13 +192,6 @@ public class ControlLoopEventManager implements StepContext, Serializable { return TimeUnit.MILLISECONDS.convert(timeout, TimeUnit.SECONDS); } - /** - * Requests a lock. This requests the lock for the time that remains before the - * timeout expires. This avoids having to extend the lock. - * - * @param targetEntity entity to be locked - * @return a future that can be used to await the lock - */ @Override public synchronized CompletableFuture<OperationOutcome> requestLock(String targetEntity) { @@ -214,6 +210,58 @@ public class ControlLoopEventManager implements StepContext, Serializable { return data.getFuture(); } + @Override + public synchronized CompletableFuture<OperationOutcome> releaseLock(String targetEntity) { + LockData data = target2lock.remove(targetEntity); + + if (data == null) { + // lock did not exist - immediately return a success + OperationOutcome outcome = makeUnlockOutcome(targetEntity); + outcome.setEnd(outcome.getStart()); + onComplete(outcome); + + return CompletableFuture.completedFuture(outcome); + } + + /* + * previous lock operation may not have completed yet, thus we tack the unlock + * operation onto it. + * + * Note: we must invoke free(), asynchronously (i.e., using whenCompleteAsync()), + * as it may block + */ + + return data.getFuture().whenCompleteAsync((lockOutcome, thrown) -> { + + OperationOutcome outcome = makeUnlockOutcome(targetEntity); + + try { + data.free(); + + } catch (RuntimeException e) { + logger.warn("failed to unlock {}", targetEntity, e); + outcome.setResult(OperationResult.FAILURE_EXCEPTION); + outcome.setMessage(ControlLoopOperation.FAILED_MSG + ": " + e.getMessage()); + } + + outcome.setEnd(Instant.now()); + onComplete(outcome); + + }, getBlockingExecutor()); + } + + private OperationOutcome makeUnlockOutcome(String targetEntity) { + OperationOutcome outcome = new OperationOutcome(); + outcome.setActor(ActorConstants.LOCK_ACTOR); + outcome.setOperation(ActorConstants.UNLOCK_OPERATION); + outcome.setTarget(targetEntity); + outcome.setResult(OperationResult.SUCCESS); + outcome.setMessage(ControlLoopOperation.SUCCESS_MSG); + outcome.setFinalOutcome(true); + outcome.setStart(Instant.now()); + return outcome; + } + public void onStart(OperationOutcome outcome) { outcomes.add(outcome); } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/StepContext.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/StepContext.java index 5251b7acc..319cc64a9 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/StepContext.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/StepContext.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 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. @@ -69,4 +69,17 @@ public interface StepContext { * @return a future that can be used to await the lock */ public CompletableFuture<OperationOutcome> requestLock(String targetEntity); + + /** + * Releases a lock. + * <p/> + * Note: once this has been invoked, whether or not the "release" operation succeeds, + * subsequent calls to {@link #requestLock(String)} for the same target entity may + * always fail, and subsequent calls to {@link #releaseLock(String)} may always + * succeed, depending on the implementation. + * + * @param targetEntity entity to be locked + * @return a future that can be used to await the release operation + */ + public CompletableFuture<OperationOutcome> releaseLock(String targetEntity); } |