diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceCallbackTest.java b/source/java/org/alfresco/repo/transfer/TransferServiceCallbackTest.java index 2c0ebf7666..abc2241a7d 100644 --- a/source/java/org/alfresco/repo/transfer/TransferServiceCallbackTest.java +++ b/source/java/org/alfresco/repo/transfer/TransferServiceCallbackTest.java @@ -21,6 +21,7 @@ package org.alfresco.repo.transfer; import static org.mockito.Matchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -404,10 +405,6 @@ public class TransferServiceCallbackTest extends TestCase event.setTransferState(TransferState.COMMITTING); expectedEvents.add(event); - event = new TransferEventCommittingStatus(); - event.setTransferState(TransferState.COMMITTING); - expectedEvents.add(event); - event = new TransferEventCommittingStatus(); event.setTransferState(TransferState.COMMITTING); 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 expectedEvents = new ArrayList(); + 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 expectedEvents) { ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(TransferEvent.class); diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java b/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java index 049a2bc97a..5f0b53759a 100644 --- a/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java +++ b/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java @@ -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 if (progress.getStatus() == TransferProgress.Status.ERROR) { @@ -694,7 +686,16 @@ public class TransferServiceImpl2 implements TransferService2 clientState = ClientTransferState.Finished; 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; break; @@ -828,7 +829,17 @@ public class TransferServiceImpl2 implements TransferService2 { logger.debug("Exception - unable to transfer", 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; + } } }