summaryrefslogtreecommitdiffstats
path: root/controlloop/common/eventmanager/src/main/java
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2021-05-03 09:11:30 -0400
committerJim Hahn <jrh3@att.com>2021-05-03 10:11:09 -0400
commitcbdf437729ca4d010147acfb208ecd90ef65777c (patch)
tree1505d656c5c455b6a0f69d533244a86e8a0879d7 /controlloop/common/eventmanager/src/main/java
parent9496f31d3b2a1674f57a0395d050be0d9c6b87f0 (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/java')
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ActorConstants.java3
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java64
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/StepContext.java15
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);
}