From bfbc29ddc69185397d33b3d12d4d6fd5e2044152 Mon Sep 17 00:00:00 2001 From: Josh Stark Date: Sun, 18 Oct 2015 12:15:39 +0100 Subject: [PATCH] Implemented TransferStrategies --- .../workflow/DisconnectWorkflowStep.java | 14 +++++ .../workflow/DownloadFilesWorkflowStep.java | 2 + .../workflow/FilterFilesWorkflowStep.java | 2 +- .../workflow/actions/MoveFileAction.java | 5 ++ .../actions/PushbulletNotifyAction.java | 5 ++ .../FilesAndFoldersTranferStrategy.java | 18 +++++- .../transfer/FilesOnlyTransferStrategy.java | 21 ++++++- .../workflow/transfer/TransferStrategy.java | 36 ++++++++++- .../workflow/DisconnectWorkflowStepTest.java | 63 +++++++++++++++++++ .../DownloadFilesWorkflowStepTest.java | 8 +++ .../FilesAndFoldersTranferStrategyTest.java | 47 ++++++++++++++ .../FilesOnlyTransferStrategyTest.java | 49 +++++++++++++++ .../transfer/TransferStrategyTest.java | 53 +++++++++++++++- 13 files changed, 315 insertions(+), 8 deletions(-) create mode 100644 src/test/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStepTest.java create mode 100644 src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategyTest.java create mode 100644 src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategyTest.java diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStep.java b/src/main/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStep.java index ee90f58..909aaf8 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStep.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStep.java @@ -1,8 +1,22 @@ package io.linuxserver.davos.schedule.workflow; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.linuxserver.davos.transfer.ftp.exception.FTPException; + public class DisconnectWorkflowStep extends WorkflowStep { + private static final Logger LOGGER = LoggerFactory.getLogger(DisconnectWorkflowStep.class); + @Override public void runStep(ScheduleWorkflow schedule) { + + try { + schedule.getClient().disconnect(); + } catch (FTPException e) { + LOGGER.error("Unable to disconnect from host. Error was: {}", e.getMessage()); + LOGGER.debug("Stacktrace", e); + } } } diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStep.java b/src/main/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStep.java index afd9555..953a72e 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStep.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStep.java @@ -30,6 +30,8 @@ public class DownloadFilesWorkflowStep extends WorkflowStep { TransferStrategy strategyToUse = transferStrategyFactory.getStrategy(config.getTransferType(), schedule.getConnection()); LOGGER.debug("Strategy chosen for downloads is {}, selected {}", config.getTransferType(), strategyToUse); + strategyToUse.setPostDownloadActions(schedule.getConfig().getActions()); + LOGGER.debug("PostDownloadActions {} have been set against chosen strategy", schedule.getConfig().getActions()); try { diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/FilterFilesWorkflowStep.java b/src/main/java/io/linuxserver/davos/schedule/workflow/FilterFilesWorkflowStep.java index 5952eb0..76422bf 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/FilterFilesWorkflowStep.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/FilterFilesWorkflowStep.java @@ -38,7 +38,7 @@ public class FilterFilesWorkflowStep extends WorkflowStep { if (filters.isEmpty()) { - LOGGER.debug("Filter list was empty. Adding all found files to list"); + LOGGER.info("Filter list was empty. Adding all found files to list"); ((DownloadFilesWorkflowStep) nextStep).setFilesToDownload(filesToFilter); } else { diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/actions/MoveFileAction.java b/src/main/java/io/linuxserver/davos/schedule/workflow/actions/MoveFileAction.java index 3ee740d..61e09f4 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/actions/MoveFileAction.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/actions/MoveFileAction.java @@ -36,4 +36,9 @@ public class MoveFileAction implements PostDownloadAction { LOGGER.debug("Full stack trace on error", e); } } + + @Override + public String toString() { + return getClass().getSimpleName(); + } } diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/actions/PushbulletNotifyAction.java b/src/main/java/io/linuxserver/davos/schedule/workflow/actions/PushbulletNotifyAction.java index b02e8b3..7f0d71e 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/actions/PushbulletNotifyAction.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/actions/PushbulletNotifyAction.java @@ -45,6 +45,11 @@ public class PushbulletNotifyAction implements PostDownloadAction { LOGGER.error("Unable to complete notification to Pushbullet. Given error: {}", e.getMessage()); } } + + @Override + public String toString() { + return getClass().getSimpleName(); + } @JsonIgnoreProperties(ignoreUnknown = true) class PushbulletResponse { diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategy.java b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategy.java index d5c7402..61c51fd 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategy.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategy.java @@ -1,16 +1,32 @@ package io.linuxserver.davos.schedule.workflow.transfer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.linuxserver.davos.transfer.ftp.FTPFile; import io.linuxserver.davos.transfer.ftp.connection.Connection; +import io.linuxserver.davos.util.FileUtils; public class FilesAndFoldersTranferStrategy extends TransferStrategy { + private static final Logger LOGGER = LoggerFactory.getLogger(FilesAndFoldersTranferStrategy.class); + public FilesAndFoldersTranferStrategy(Connection connection) { super(connection); } @Override public void transferFile(FTPFile fileToTransfer, String destination) { - // TODO Auto-generated method stub + + String filename = fileToTransfer.getName(); + String cleanFilePath = FileUtils.ensureTrailingSlash(fileToTransfer.getAbsolutePath()); + String cleanDestination = FileUtils.ensureTrailingSlash(destination); + + LOGGER.info("Downloading {} to {}", cleanFilePath + filename, cleanDestination); + connection.download(cleanFilePath + filename, cleanDestination); + LOGGER.info("Successfully downloaded file."); + + LOGGER.info("Running post download actions on {}", filename); + runPostDownloadAction(fileToTransfer); } } diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategy.java b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategy.java index 9fc26d5..5d61f91 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategy.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategy.java @@ -1,16 +1,35 @@ package io.linuxserver.davos.schedule.workflow.transfer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.linuxserver.davos.transfer.ftp.FTPFile; import io.linuxserver.davos.transfer.ftp.connection.Connection; +import io.linuxserver.davos.util.FileUtils; public class FilesOnlyTransferStrategy extends TransferStrategy { + private static final Logger LOGGER = LoggerFactory.getLogger(FilesOnlyTransferStrategy.class); + public FilesOnlyTransferStrategy(Connection connection) { super(connection); } @Override public void transferFile(FTPFile fileToTransfer, String destination) { - // TODO Auto-generated method stub + + String filename = fileToTransfer.getName(); + String cleanFilePath = FileUtils.ensureTrailingSlash(fileToTransfer.getAbsolutePath()); + String cleanDestination = FileUtils.ensureTrailingSlash(destination); + + if (!fileToTransfer.isDirectory()) { + + LOGGER.info("Downloading {} to {}", cleanFilePath + filename, cleanDestination); + connection.download(cleanFilePath + filename, cleanDestination); + LOGGER.info("Successfully downloaded file."); + + LOGGER.info("Running post download actions on {}", filename); + runPostDownloadAction(fileToTransfer); + } } } diff --git a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategy.java b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategy.java index 2173cf9..2bebb9e 100644 --- a/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategy.java +++ b/src/main/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategy.java @@ -1,20 +1,52 @@ package io.linuxserver.davos.schedule.workflow.transfer; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.linuxserver.davos.schedule.workflow.actions.PostDownloadAction; +import io.linuxserver.davos.schedule.workflow.actions.PostDownloadExecution; import io.linuxserver.davos.transfer.ftp.FTPFile; import io.linuxserver.davos.transfer.ftp.connection.Connection; public abstract class TransferStrategy { + private static final Logger LOGGER = LoggerFactory.getLogger(TransferStrategy.class); + protected Connection connection; + private List postDownloadActions = new ArrayList(); public TransferStrategy(Connection connection) { this.connection = connection; } - public abstract void transferFile(FTPFile fileToTransfer, String destination); - + public void setPostDownloadActions(List postDownloadActions) { + this.postDownloadActions = postDownloadActions; + } + @Override public String toString() { return getClass().getSimpleName(); } + + public abstract void transferFile(FTPFile fileToTransfer, String destination); + + protected void runPostDownloadAction(FTPFile file) { + + if (null == postDownloadActions) { + + LOGGER.warn("Post download actions have been nulled! This should not happen. Will not attempt run of actions"); + return; + } + + for (PostDownloadAction action : postDownloadActions) { + + PostDownloadExecution execution = new PostDownloadExecution(); + execution.fileName = file.getName(); + + action.execute(execution); + } + } } diff --git a/src/test/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStepTest.java b/src/test/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStepTest.java new file mode 100644 index 0000000..9dc182f --- /dev/null +++ b/src/test/java/io/linuxserver/davos/schedule/workflow/DisconnectWorkflowStepTest.java @@ -0,0 +1,63 @@ +package io.linuxserver.davos.schedule.workflow; + +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import io.linuxserver.davos.schedule.ScheduleConfiguration; +import io.linuxserver.davos.transfer.ftp.FileTransferType; +import io.linuxserver.davos.transfer.ftp.TransferProtocol; +import io.linuxserver.davos.transfer.ftp.client.Client; +import io.linuxserver.davos.transfer.ftp.client.UserCredentials; +import io.linuxserver.davos.transfer.ftp.connection.Connection; +import io.linuxserver.davos.transfer.ftp.exception.ClientDisconnectException; + +public class DisconnectWorkflowStepTest { + + private DisconnectWorkflowStep workflowStep = new DisconnectWorkflowStep(); + + @Mock + private Client mockClient; + + @Mock + private Connection mockConnection; + + @Before + public void setUp() { + initMocks(this); + } + + @Test + public void runStepShouldCloseTheConnection() { + + ScheduleConfiguration config = new ScheduleConfiguration("", TransferProtocol.SFTP, "", 0, new UserCredentials("", ""), + "", "", FileTransferType.FILES_ONLY); + + ScheduleWorkflow schedule = new ScheduleWorkflow(config); + schedule.setConnection(mockConnection); + schedule.setClient(mockClient); + + workflowStep.runStep(schedule); + + verify(mockClient).disconnect(); + } + + @Test + public void ifDisconnectingFailsThenDoNothing() { + + ScheduleConfiguration config = new ScheduleConfiguration("", TransferProtocol.SFTP, "", 0, new UserCredentials("", ""), + "", "", FileTransferType.FILES_ONLY); + + ScheduleWorkflow schedule = new ScheduleWorkflow(config); + schedule.setConnection(mockConnection); + schedule.setClient(mockClient); + + doThrow(new ClientDisconnectException()).when(mockClient).disconnect(); + + workflowStep.runStep(schedule); + } +} diff --git a/src/test/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStepTest.java b/src/test/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStepTest.java index 070a5e6..1d9a59a 100644 --- a/src/test/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStepTest.java +++ b/src/test/java/io/linuxserver/davos/schedule/workflow/DownloadFilesWorkflowStepTest.java @@ -18,6 +18,8 @@ import org.mockito.Mock; import org.mockito.Mockito; import io.linuxserver.davos.schedule.ScheduleConfiguration; +import io.linuxserver.davos.schedule.workflow.actions.MoveFileAction; +import io.linuxserver.davos.schedule.workflow.actions.PostDownloadAction; import io.linuxserver.davos.schedule.workflow.transfer.TransferStrategy; import io.linuxserver.davos.schedule.workflow.transfer.TransferStrategyFactory; import io.linuxserver.davos.transfer.ftp.FTPFile; @@ -72,6 +74,11 @@ public class DownloadFilesWorkflowStepTest { ScheduleConfiguration config = new ScheduleConfiguration("", TransferProtocol.SFTP, "", 0, new UserCredentials("", ""), "", "local/", FileTransferType.FILES_ONLY); + + ArrayList actions = new ArrayList(); + actions.add(new MoveFileAction("", "")); + + config.setActions(actions); ScheduleWorkflow schedule = new ScheduleWorkflow(config); schedule.setConnection(mockConnection); @@ -79,6 +86,7 @@ public class DownloadFilesWorkflowStepTest { verify(mockTransferStrategyFactory).getStrategy(FileTransferType.FILES_ONLY, mockConnection); + verify(mockTransferStrategy).setPostDownloadActions(actions); verify(mockTransferStrategy).transferFile(file, "local/"); verify(mockTransferStrategy).transferFile(file2, "local/"); } diff --git a/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategyTest.java b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategyTest.java new file mode 100644 index 0000000..88cbb52 --- /dev/null +++ b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesAndFoldersTranferStrategyTest.java @@ -0,0 +1,47 @@ +package io.linuxserver.davos.schedule.workflow.transfer; + +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import io.linuxserver.davos.transfer.ftp.FTPFile; +import io.linuxserver.davos.transfer.ftp.connection.Connection; + +public class FilesAndFoldersTranferStrategyTest { + + private FilesAndFoldersTranferStrategy strategy; + + @Mock + private Connection mockConnection; + + @Before + public void setUp() { + + initMocks(this); + + strategy = new FilesAndFoldersTranferStrategy(mockConnection); + } + + @Test + public void strategyShouldCallDownloadMethodForFiles() { + + FTPFile file = new FTPFile("file1", 0, "remotePath/", 0, false); + + strategy.transferFile(file, "destination"); + + verify(mockConnection).download("remotePath/file1", "destination/"); + } + + @Test + public void strategyShouldCallDownloadMethodForDirectories() { + + FTPFile file = new FTPFile("file1", 0, "remotePath/", 0, true); + + strategy.transferFile(file, "destination"); + + verify(mockConnection).download("remotePath/file1", "destination/"); + } +} diff --git a/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategyTest.java b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategyTest.java new file mode 100644 index 0000000..21cacfe --- /dev/null +++ b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/FilesOnlyTransferStrategyTest.java @@ -0,0 +1,49 @@ +package io.linuxserver.davos.schedule.workflow.transfer; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import io.linuxserver.davos.transfer.ftp.FTPFile; +import io.linuxserver.davos.transfer.ftp.connection.Connection; + +public class FilesOnlyTransferStrategyTest { + + private FilesOnlyTransferStrategy strategy; + + @Mock + private Connection mockConnection; + + @Before + public void setUp() { + + initMocks(this); + + strategy = new FilesOnlyTransferStrategy(mockConnection); + } + + @Test + public void strategyShouldCallDownloadMethodForFiles() { + + FTPFile file = new FTPFile("file1", 0, "remotePath/", 0, false); + + strategy.transferFile(file, "destination"); + + verify(mockConnection).download("remotePath/file1", "destination/"); + } + + @Test + public void strategyShouldNotCallDownloadMethodForDirectories() { + + FTPFile file = new FTPFile("file1", 0, "remotePath/", 0, true); + + strategy.transferFile(file, "destination"); + + verify(mockConnection, never()).download(anyString(), anyString()); + } +} diff --git a/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategyTest.java b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategyTest.java index 0dc31d5..035b53a 100644 --- a/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategyTest.java +++ b/src/test/java/io/linuxserver/davos/schedule/workflow/transfer/TransferStrategyTest.java @@ -1,9 +1,16 @@ package io.linuxserver.davos.schedule.workflow.transfer; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import io.linuxserver.davos.schedule.workflow.actions.PostDownloadAction; +import io.linuxserver.davos.schedule.workflow.actions.PostDownloadExecution; import io.linuxserver.davos.transfer.ftp.FTPFile; import io.linuxserver.davos.transfer.ftp.connection.Connection; @@ -14,8 +21,36 @@ public class TransferStrategyTest { assertThat(new TestTransferStrategy(null).toString()).isEqualTo("TestTransferStrategy"); assertThat(new AnotherTestTransferStrategy(null).toString()).isEqualTo("AnotherTestTransferStrategy"); } - - + + @Test + public void runPostDownloadActionShouldCallAllGivenActionsWithTheFile() { + + ArgumentCaptor captor = ArgumentCaptor.forClass(PostDownloadExecution.class); + + DownloadActionImplTestTransferStrategy strategy = new DownloadActionImplTestTransferStrategy(null); + + PostDownloadAction mockAction1 = mock(PostDownloadAction.class); + PostDownloadAction mockAction2 = mock(PostDownloadAction.class); + + strategy.setPostDownloadActions(Arrays.asList(mockAction1, mockAction2)); + + strategy.transferFile(new FTPFile("file1", 0, null, 0, false), "destination/"); + + verify(mockAction1).execute(captor.capture()); + verify(mockAction2).execute(captor.capture()); + + assertThat(captor.getAllValues().get(0).fileName).isEqualTo("file1"); + assertThat(captor.getAllValues().get(1).fileName).isEqualTo("file1"); + } + + @Test + public void ensureNulLActionsAreCheckedBeforeAttemptingToRun() { + + DownloadActionImplTestTransferStrategy strategy = new DownloadActionImplTestTransferStrategy(null); + strategy.setPostDownloadActions(null); + strategy.transferFile(new FTPFile("file1", 0, null, 0, false), "destination/"); + } + class TestTransferStrategy extends TransferStrategy { public TestTransferStrategy(Connection connection) { @@ -26,7 +61,7 @@ public class TransferStrategyTest { public void transferFile(FTPFile fileToTransfer, String destination) { } } - + class AnotherTestTransferStrategy extends TransferStrategy { public AnotherTestTransferStrategy(Connection connection) { @@ -37,4 +72,16 @@ public class TransferStrategyTest { public void transferFile(FTPFile fileToTransfer, String destination) { } } + + class DownloadActionImplTestTransferStrategy extends TransferStrategy { + + public DownloadActionImplTestTransferStrategy(Connection connection) { + super(connection); + } + + @Override + public void transferFile(FTPFile fileToTransfer, String destination) { + runPostDownloadAction(fileToTransfer); + } + } }