mirror of https://github.com/apache/nifi.git
NIFI-1984: Ensure that if an Exception is thrown by the 'Deletion Task' when calling NaiveRevisionManager.deleteRevision() that the locking is appropriately cleaned up
This closes #510
This commit is contained in:
parent
37488d2789
commit
18133988a0
|
@ -209,7 +209,21 @@ public class NaiveRevisionManager implements RevisionManager {
|
||||||
if (successCount == revisionList.size()) {
|
if (successCount == revisionList.size()) {
|
||||||
logger.debug("Successfully verified Revision Claim for all revisions {}", claim);
|
logger.debug("Successfully verified Revision Claim for all revisions {}", claim);
|
||||||
|
|
||||||
final T taskValue = task.performTask();
|
final T taskValue;
|
||||||
|
try {
|
||||||
|
taskValue = task.performTask();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
logger.debug("Failed to perform Claim Deletion task. Will relinquish the Revision Claims for the following revisions: {}", revisionList);
|
||||||
|
|
||||||
|
for (final Revision revision : revisionList) {
|
||||||
|
final RevisionLock revisionLock = getRevisionLock(revision);
|
||||||
|
revisionLock.unlock(revision, revision, user.getUserName());
|
||||||
|
logger.debug("Relinquished lock for {}", revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
for (final Revision revision : revisionList) {
|
for (final Revision revision : revisionList) {
|
||||||
deleteRevisionLock(revision);
|
deleteRevisionLock(revision);
|
||||||
logger.debug("Deleted Revision {}", revision);
|
logger.debug("Deleted Revision {}", revision);
|
||||||
|
|
|
@ -615,4 +615,100 @@ public class TestNaiveRevisionManager {
|
||||||
assertTrue(component1Seen);
|
assertTrue(component1Seen);
|
||||||
assertTrue(component2Seen);
|
assertTrue(component2Seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 5000)
|
||||||
|
public void testWriteLockReleasedWhenClaimCanceledByRevision() {
|
||||||
|
final RevisionManager revisionManager = new NaiveRevisionManager(2, TimeUnit.SECONDS);
|
||||||
|
final Revision component1V1 = new Revision(1L, CLIENT_1, COMPONENT_1);
|
||||||
|
|
||||||
|
final RevisionClaim claim = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim);
|
||||||
|
assertEquals(1, claim.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim.getRevisions().iterator().next());
|
||||||
|
|
||||||
|
assertTrue(revisionManager.cancelClaim(component1V1));
|
||||||
|
|
||||||
|
final RevisionClaim claim2 = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim2);
|
||||||
|
assertEquals(1, claim2.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim2.getRevisions().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 5000)
|
||||||
|
public void testWriteLockReleasedWhenClaimCanceledByComponentId() {
|
||||||
|
final RevisionManager revisionManager = new NaiveRevisionManager(2, TimeUnit.SECONDS);
|
||||||
|
final Revision component1V1 = new Revision(1L, CLIENT_1, COMPONENT_1);
|
||||||
|
|
||||||
|
final RevisionClaim claim = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim);
|
||||||
|
assertEquals(1, claim.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim.getRevisions().iterator().next());
|
||||||
|
|
||||||
|
assertTrue(revisionManager.cancelClaim(COMPONENT_1));
|
||||||
|
|
||||||
|
final RevisionClaim claim2 = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim2);
|
||||||
|
assertEquals(1, claim2.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim2.getRevisions().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 5000)
|
||||||
|
public void testDeleteRevisionUnlocksClaimIfExceptionThrown() {
|
||||||
|
final RevisionManager revisionManager = new NaiveRevisionManager(2, TimeUnit.MINUTES);
|
||||||
|
final Revision component1V1 = new Revision(1L, CLIENT_1, COMPONENT_1);
|
||||||
|
|
||||||
|
final RevisionClaim claim = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim);
|
||||||
|
assertEquals(1, claim.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim.getRevisions().iterator().next());
|
||||||
|
|
||||||
|
final RuntimeException re = new RuntimeException("Intentional Unit Test Exception");
|
||||||
|
try {
|
||||||
|
revisionManager.deleteRevision(claim, USER_1, () -> {
|
||||||
|
throw re;
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.fail("deleteRevision() method did not propagate Exception thrown");
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
assertTrue(re == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that we can obtain a read lock
|
||||||
|
revisionManager.get(COMPONENT_1, rev -> rev);
|
||||||
|
|
||||||
|
final RevisionClaim claim2 = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim2);
|
||||||
|
assertEquals(1, claim2.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim2.getRevisions().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 5000)
|
||||||
|
public void testUpdateRevisionUnlocksClaimIfExceptionThrown() {
|
||||||
|
final RevisionManager revisionManager = new NaiveRevisionManager(2, TimeUnit.MINUTES);
|
||||||
|
final Revision component1V1 = new Revision(1L, CLIENT_1, COMPONENT_1);
|
||||||
|
|
||||||
|
final RevisionClaim claim = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim);
|
||||||
|
assertEquals(1, claim.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim.getRevisions().iterator().next());
|
||||||
|
|
||||||
|
final RuntimeException re = new RuntimeException("Intentional Unit Test Exception");
|
||||||
|
try {
|
||||||
|
revisionManager.updateRevision(claim, USER_1, () -> {
|
||||||
|
throw re;
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.fail("updateRevision() method did not propagate Exception thrown");
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
assertTrue(re == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that we can obtain a read lock
|
||||||
|
revisionManager.get(COMPONENT_1, rev -> rev);
|
||||||
|
|
||||||
|
final RevisionClaim claim2 = revisionManager.requestClaim(component1V1, USER_1);
|
||||||
|
assertNotNull(claim2);
|
||||||
|
assertEquals(1, claim2.getRevisions().size());
|
||||||
|
assertEquals(component1V1, claim2.getRevisions().iterator().next());
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue