mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
29.22.2018 cdd5a70a92a808d063f32f1454e3584165beab53
JobResult...
1 files added
7 files modified
119 ■■■■ changed files
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java 29 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java 16 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java 18 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java 12 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java 12 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobResult.java 15 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/test/java/de/micromata/borgbutler/jobs/JobQueueTest.java 8 ●●●● patch | view | raw | blame | history
borgbutler-core/src/test/java/de/micromata/borgbutler/jobs/TestJob.java 9 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
@@ -3,6 +3,7 @@
import de.micromata.borgbutler.config.BorgRepoConfig;
import de.micromata.borgbutler.data.Archive;
import de.micromata.borgbutler.data.Repository;
import de.micromata.borgbutler.jobs.JobResult;
import de.micromata.borgbutler.json.JsonUtils;
import de.micromata.borgbutler.json.borg.*;
import de.micromata.borgbutler.utils.DateUtils;
@@ -35,10 +36,11 @@
        BorgCommand command = new BorgCommand()
                .setParams("--version")
                .setDescription("Getting borg version.");
        String version = execute(command).getResult();
        if (command.getResultStatus() != BorgCommand.ResultStatus.OK) {
        JobResult<String> jobResult = execute(command).getResult();
        if (jobResult.getStatus() != JobResult.Status.OK) {
            return null;
        }
        String version = jobResult.getResultObject();
        log.info("Borg version: " + version);
        return version;
    }
@@ -55,10 +57,11 @@
                .setCommand("info")
                .setParams("--json")
                .setDescription("Loading info of repo '" + repoConfig.getDisplayName() + "'.");
        String result = execute(command).getResult();
        if (command.getResultStatus() != BorgCommand.ResultStatus.OK) {
        JobResult<String> jobResult = execute(command).getResult();
        if (jobResult.getStatus() != JobResult.Status.OK) {
            return null;
        }
        String result = jobResult.getResultObject();
        BorgRepoInfo repoInfo = JsonUtils.fromJson(BorgRepoInfo.class, result);
        BorgRepository borgRepository = repoInfo.getRepository();
        Repository repository = new Repository()
@@ -87,11 +90,12 @@
                .setCommand("list")
                .setParams("--json")
                .setDescription("Loading list of archives of repo '" + repoConfig.getDisplayName() + "'.");
        String result = execute(command).getResult();
        if (command.getResultStatus() != BorgCommand.ResultStatus.OK) {
        JobResult<String> jobResult = execute(command).getResult();
        if (jobResult.getStatus() != JobResult.Status.OK) {
            log.error("Can't load archives from repo '" + repository.getName() + "'.");
            return;
        }
        String result = jobResult.getResultObject();
        BorgRepoList repoList = JsonUtils.fromJson(BorgRepoList.class, result);
        if (repoList == null || CollectionUtils.isEmpty(repoList.getArchives())) {
            log.error("Can't load archives from repo '" + repository.getName() + "'.");
@@ -128,10 +132,11 @@
                .setArchive(archive.getName())
                .setParams("--json")
                .setDescription("Loading info of archive '" + archive.getName() + "' of repo '" + repoConfig.getDisplayName() + "'.");
        String result = execute(command).getResult();
        if (command.getResultStatus() != BorgCommand.ResultStatus.OK) {
        JobResult<String> jobResult = execute(command).getResult();
        if (jobResult.getStatus() != JobResult.Status.OK) {
            return;
        }
        String result = jobResult.getResultObject();
        BorgArchiveInfo archiveInfo = JsonUtils.fromJson(BorgArchiveInfo.class, result);
        if (archiveInfo == null) {
            log.error("Archive '" + command.getRepoArchive() + "' not found.");
@@ -158,8 +163,7 @@
                .setHostname(borgArchive.getHostname())
                .setUsername(borgArchive.getUsername())
                .setEnd(DateUtils.format(borgArchive.getEnd()))
                .setDuration(borgArchive.getDuration())
        ;
                .setDuration(borgArchive.getDuration());
    }
    public static List<BorgFilesystemItem> listArchiveContent(BorgRepoConfig repoConfig, Archive archive) {
@@ -169,11 +173,12 @@
                .setArchive(archive.getName())
                .setParams("--json-lines")
                .setDescription("Loading list of files of archive '" + archive.getName() + "' of repo '" + repoConfig.getDisplayName() + "'.");
        String result = execute(command).getResult();
        List<BorgFilesystemItem> content = new ArrayList<>();
        if (command.getResultStatus() != BorgCommand.ResultStatus.OK) {
        JobResult<String> jobResult = execute(command).getResult();
        if (jobResult.getStatus() != JobResult.Status.OK) {
            return content;
        }
        String result = jobResult.getResultObject();
        try (Scanner scanner = new Scanner(result)) {
            while (scanner.hasNextLine()) {
                String json = scanner.nextLine();
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java
@@ -2,7 +2,6 @@
import de.micromata.borgbutler.config.BorgRepoConfig;
import de.micromata.borgbutler.config.ConfigurationHandler;
import de.micromata.borgbutler.config.Definitions;
import de.micromata.borgbutler.jobs.AbstractCommandLineJob;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.environment.EnvironmentUtils;
@@ -17,7 +16,7 @@
 * A queue is important because Borg doesn't support parallel calls for one repository.
 * For each repository one single queue is allocated.
 */
public class BorgJob extends AbstractCommandLineJob {
public class BorgJob extends AbstractCommandLineJob<String> {
    private Logger log = LoggerFactory.getLogger(BorgJob.class);
    private BorgCommand command;
@@ -50,19 +49,6 @@
    }
    @Override
    protected void afterSuccess() {
        command.setResultStatus(BorgCommand.ResultStatus.OK);
        command.setResponse(outputStream.toString(Definitions.STD_CHARSET));
    }
    @Override
    protected void afterFailure(Exception ex) {
        command.setResultStatus(BorgCommand.ResultStatus.ERROR);
        command.setResponse(outputStream.toString(Definitions.STD_CHARSET));
        log.error("Response: " + command.getAbbreviatedResponse());
    }
    @Override
    protected Map<String, String> getEnvironment() throws IOException {
        BorgRepoConfig repoConfig = command.getRepoConfig();
        if (repoConfig == null) {
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java
@@ -18,7 +18,7 @@
 * A queue is important because Borg doesn't support parallel calls for one repository.
 * For each repository one single queue is allocated.
 */
public abstract class AbstractCommandLineJob extends AbstractJob<String> {
public abstract class AbstractCommandLineJob<T> extends AbstractJob<T> {
    private Logger log = LoggerFactory.getLogger(AbstractCommandLineJob.class);
    private ExecuteWatchdog watchdog;
    @Getter
@@ -53,7 +53,7 @@
    }
    @Override
    public String execute() {
    public JobResult<String> execute() {
        getCommandLineAsString();
        DefaultExecutor executor = new DefaultExecutor();
        if (workingDirectory != null) {
@@ -91,15 +91,17 @@
                : "Executing '" + commandLineAsString + "'...";
        log.info(msg);
        this.executeStarted = true;
        JobResult<String> result = new JobResult<>();
        try {
            executor.execute(commandLine, getEnvironment());
            afterSuccess();
            result.setStatus(JobResult.Status.OK);
            log.info(msg + " Done.");
        } catch (Exception ex) {
            result.setStatus(JobResult.Status.ERROR);
            failed();
            afterFailure(ex);
        }
        return outputStream.toString(Definitions.STD_CHARSET);
        result.setResultObject(outputStream.toString(Definitions.STD_CHARSET));
        return result;
    }
    @Override
@@ -112,12 +114,6 @@
        }
    }
    protected void afterSuccess() {
    }
    protected void afterFailure(Exception ex) {
    }
    protected Map<String, String> getEnvironment() throws IOException {
        return null;
    }
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java
@@ -29,7 +29,9 @@
    private String statusText;
    @Getter(AccessLevel.PACKAGE)
    @Setter(AccessLevel.PACKAGE)
    private Future<T> future;
    // TODO: JobResult
    private Future<JobResult<T>> future;
    public void cancel() {
        if (this.getStatus() == Status.QUEUED) {
@@ -53,7 +55,7 @@
     * Waits for and gets the result.
     * @return
     */
    public T getResult() {
    public JobResult<T> getResult() {
        try {
            return future.get();
        } catch (InterruptedException | ExecutionException ex) {
@@ -62,6 +64,10 @@
        return null;
    }
    public T getResultObject() {
        return getResult().getResultObject();
    }
    protected void failed() {
        if (this.status == Status.CANCELLED) {
            // do nothing. It's normal that cancelled jobs fail.
@@ -83,7 +89,7 @@
        return false;
    }
    public abstract T execute();
    public abstract JobResult execute();
    /**
     * A job is identified by this id. If a job with the same id is already queued (not yet finished), this job will
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java
@@ -30,7 +30,7 @@
     * @param job
     * @return The given job (if it's not already running or queued), otherwise the already running or queued job.
     */
    public AbstractJob append(AbstractJob<T> job) {
    public AbstractJob append(AbstractJob job) {
        synchronized (queue) {
            for (AbstractJob queuedJob : queue) {
                if (Objects.equals(queuedJob.getId(), job.getId())) {
@@ -83,15 +83,15 @@
        }
    }
    private class CallableTask implements Callable<T> {
        private AbstractJob<T> job;
    private class CallableTask implements Callable<JobResult<T>> {
        private AbstractJob job;
        private CallableTask(AbstractJob<T> job) {
        private CallableTask(AbstractJob job) {
            this.job = job;
        }
        @Override
        public T call() throws Exception {
        public JobResult<T> call() throws Exception {
            if (job.isCancelledRequested()) {
                job.setStatus(AbstractJob.Status.CANCELLED);
                return null;
@@ -99,7 +99,7 @@
            try {
                log.info("Starting job: " + job.getId());
                job.setStatus(AbstractJob.Status.RUNNING);
                T result = job.execute();
                JobResult<T> result = job.execute();
                if (!job.isFinished()) {
                    // Don't overwrite status failed set by job.
                    job.setStatus(AbstractJob.Status.DONE);
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobResult.java
New file
@@ -0,0 +1,15 @@
package de.micromata.borgbutler.jobs;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class JobResult<T> {
    public enum Status {OK, ERROR}
    @Getter
    @Setter(AccessLevel.PACKAGE)
    private Status status;
    @Getter
    @Setter
    private T resultObject;
}
borgbutler-core/src/test/java/de/micromata/borgbutler/jobs/JobQueueTest.java
@@ -64,7 +64,7 @@
        TestJob job = (TestJob) queue.getQueuedJob(5);
        assertEquals(AbstractJob.Status.QUEUED, job.getStatus());
        String result = job1.getResult();
        String result = job1.getResultObject();
        assertEquals("10\n", result);
        assertEquals(AbstractJob.Status.DONE, job1.getStatus());
@@ -77,7 +77,7 @@
        job.cancel();
        assertEquals(AbstractJob.Status.CANCELLED, job.getStatus());
        result = job1.getResult();
        result = job1.getResultObject();
        assertEquals("10\n", result);
        assertEquals(0, queue.getQueueSize());
@@ -118,7 +118,7 @@
        assertTrue(counter > 0);
        assertEquals(AbstractJob.Status.CANCELLED, job.getStatus());
        job = (TestJob)queue.getQueuedJob(10);
        assertEquals("10\n", job.getResult());
        assertEquals("10\n", job.getResultObject());
        List<AbstractJob> doneJobs = queue.getDoneJobs();
        assertEquals(2, doneJobs.size());
        check(((TestJob) doneJobs.get(0)), AbstractJob.Status.DONE, null);
@@ -128,7 +128,7 @@
    private void check(TestJob job, AbstractJob.Status status, String result) {
        assertEquals(status, job.getStatus());
        if (result != null) {
            assertEquals(result + "\n", job.getResult());
            assertEquals(result + "\n", job.getResultObject());
        }
    }
}
borgbutler-core/src/test/java/de/micromata/borgbutler/jobs/TestJob.java
@@ -6,7 +6,7 @@
import java.io.File;
public class TestJob extends AbstractCommandLineJob {
public class TestJob extends AbstractCommandLineJob<String> {
    private Logger log = LoggerFactory.getLogger(TestJob.class);
    private int time;
    private File counterScript;
@@ -34,11 +34,4 @@
        commandLine.addArgument(String.valueOf(this.failOn));
        return commandLine;
    }
    @Override
    protected void afterFailure(Exception ex) {
        if (failOn < 0 && getStatus() != Status.CANCELLED) {
            log.error("Error while executing script '" + getCommandLineAsString() + "': " + ex.getMessage(), ex);
        }
    }
}