Resolve ALF-4844: Transfer Locks remain if a transfer error occurs on the client prior to the commit phase

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22623 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2010-09-17 18:01:21 +00:00
parent 73025bf7e5
commit 3d447277be
2 changed files with 91 additions and 14 deletions

View File

@@ -21,6 +21,7 @@ package org.alfresco.repo.transfer;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -404,10 +405,6 @@ public class TransferServiceCallbackTest extends TestCase
event.setTransferState(TransferState.COMMITTING); event.setTransferState(TransferState.COMMITTING);
expectedEvents.add(event); expectedEvents.add(event);
event = new TransferEventCommittingStatus();
event.setTransferState(TransferState.COMMITTING);
expectedEvents.add(event);
event = new TransferEventCommittingStatus(); event = new TransferEventCommittingStatus();
event.setTransferState(TransferState.COMMITTING); event.setTransferState(TransferState.COMMITTING);
expectedEvents.add(event); expectedEvents.add(event);
@@ -479,6 +476,75 @@ public class TransferServiceCallbackTest extends TestCase
} }
} }
public void testSendContentFailed()
{
TransferProgress status0 = new TransferProgress();
status0.setStatus(Status.CANCELLED);
status0.setCurrentPosition(0);
status0.setEndPosition(0);
TransferProgress[] statuses = new TransferProgress[] {status0};
configureBasicMockTransmitter(statuses);
when(mockedTransferTransmitter.begin(target)).thenReturn(transfer);
doThrow(new TransferException("Simulate failure to write content")).when(mockedTransferTransmitter).sendManifest(any(Transfer.class), any(File.class), any(OutputStream.class));
when(mockedTransferTransmitter.getStatus(transfer)).thenReturn(statuses[0]);
TransferDefinition transferDef = new TransferDefinition();
transferDef.setNodes(folder1, file1, file2, file3);
try
{
transferService.transfer(TRANSFER_TARGET_NAME, transferDef, mockedCallback);
fail("Transfer expected to throw an exception, but it didn't.");
}
catch(TransferFailureException ex)
{
List<TransferEvent> expectedEvents = new ArrayList<TransferEvent>();
TransferEventImpl event;
event = new TransferEventEnterState();
event.setTransferState(TransferState.START);
expectedEvents.add(event);
event = new TransferEventBegin();
event.setTransferState(TransferState.START);
expectedEvents.add(event);
event = new TransferEventEndState();
event.setTransferState(TransferState.START);
expectedEvents.add(event);
event = new TransferEventEnterState();
event.setTransferState(TransferState.SENDING_SNAPSHOT);
expectedEvents.add(event);
event = new TransferEventSendingSnapshot();
event.setTransferState(TransferState.SENDING_SNAPSHOT);
expectedEvents.add(event);
event = new TransferEventEndState();
event.setTransferState(TransferState.SENDING_SNAPSHOT);
expectedEvents.add(event);
event = new TransferEventEnterState();
event.setTransferState(TransferState.ERROR);
expectedEvents.add(event);
event = new TransferEventReport();
event.setTransferState(TransferState.ERROR);
expectedEvents.add(event);
event = new TransferEventReport();
event.setTransferState(TransferState.ERROR);
expectedEvents.add(event);
event = new TransferEventError();
event.setTransferState(TransferState.ERROR);
((TransferEventError)event).setException((Exception)ex.getCause());
expectedEvents.add(event);
verifyCallback(expectedEvents);
}
}
private void verifyCallback(List<TransferEvent> expectedEvents) private void verifyCallback(List<TransferEvent> expectedEvents)
{ {
ArgumentCaptor<TransferEvent> eventCaptor = ArgumentCaptor.forClass(TransferEvent.class); ArgumentCaptor<TransferEvent> eventCaptor = ArgumentCaptor.forClass(TransferEvent.class);

View File

@@ -660,14 +660,6 @@ public class TransferServiceImpl2 implements TransferService2
} }
} }
// notify transfer progress
if (progress.getCurrentPosition() != pollPosition)
{
pollPosition = progress.getCurrentPosition();
logger.debug("committing :" + pollPosition);
eventProcessor.committing(progress.getEndPosition(), pollPosition);
}
// check status // check status
if (progress.getStatus() == TransferProgress.Status.ERROR) if (progress.getStatus() == TransferProgress.Status.ERROR)
{ {
@@ -694,7 +686,16 @@ public class TransferServiceImpl2 implements TransferService2
clientState = ClientTransferState.Finished; clientState = ClientTransferState.Finished;
break; break;
} }
else if (progress.getStatus() == TransferProgress.Status.COMPLETE)
// notify transfer progress
if (progress.getCurrentPosition() != pollPosition)
{
pollPosition = progress.getCurrentPosition();
logger.debug("committing :" + pollPosition);
eventProcessor.committing(progress.getEndPosition(), pollPosition);
}
if (progress.getStatus() == TransferProgress.Status.COMPLETE)
{ {
clientState = ClientTransferState.Finished; clientState = ClientTransferState.Finished;
break; break;
@@ -828,7 +829,17 @@ public class TransferServiceImpl2 implements TransferService2
{ {
logger.debug("Exception - unable to transfer", e); logger.debug("Exception - unable to transfer", e);
failureException = e; failureException = e;
clientState = ClientTransferState.Finished;
if (transfer != null && (clientState == ClientTransferState.Begin || clientState == ClientTransferState.Prepare))
{
// we must first inform the target repository that a client failure has occurred to allow it to
// clean up appropriately, too
clientState = ClientTransferState.Cancel;
}
else
{
clientState = ClientTransferState.Finished;
}
} }
} }