summaryrefslogtreecommitdiffstats
path: root/controlloop/common/eventmanager
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2019-09-27 11:22:47 -0400
committerJim Hahn <jrh3@att.com>2019-10-22 16:06:10 -0400
commitac5c19ddbed1ff5905d16a6359ee23b4888c717a (patch)
treeacd501248ae73dcd90b2318695acc535a9bb9dcc /controlloop/common/eventmanager
parent636a1b2fcafa5249cf2bf380dfb6e20f6fe98691 (diff)
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 <jrh3@att.com> Change-Id: I5bc9b7732f9cfc6056789b2902d9f6f838b560be
Diffstat (limited to 'controlloop/common/eventmanager')
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java133
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java24
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemory.java80
-rw-r--r--controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java226
-rw-r--r--controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/LockCallbackWorkingMemoryTest.java96
5 files changed, 420 insertions, 139 deletions
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<ControlLoopOperation> 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<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
+ public synchronized Pair<Lock, Lock> 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<GuardResult, TargetLock> 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 {
@@ -1033,18 +1039,6 @@ public class ControlLoopEventManager implements LockCallback, Serializable {
}
@Override
- public boolean isActive() {
- // TODO
- return true;
- }
-
- @Override
- public boolean releaseLock() {
- // TODO
- return false;
- }
-
- @Override
public String toString() {
return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestId=" + requestId
+ ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestId() : "null")
@@ -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<GuardResult, TargetLock> lockLock = manager.lockCurrentOperation();
- assertNotNull(lockLock);
- assertEquals(GuardResult.LOCK_ACQUIRED, lockLock.getA());
-
- LockResult<GuardResult, TargetLock> 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<Lock, Lock> 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());
+ }
+
+}