Add 'sdk/java-v2/' from commit '55f103e336ca9fb8bf1720d2ef4ee8dd4e221118'
[arvados.git] / sdk / java-v2 / src / main / java / org / arvados / client / logic / keep / static / git-logo.png
diff --git a/src/main/java/org/arvados/client/logic/keep/FileDownloader.java b/src/main/java/org/arvados/client/logic/keep/FileDownloader.java
deleted file mode 100644 (file)
index 1f694f2..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) The Arvados Authors. All rights reserved.
- *
- * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
- *
- */
-
-package org.arvados.client.logic.keep;
-
-import com.google.common.collect.Lists;
-import org.arvados.client.api.client.CollectionsApiClient;
-import org.arvados.client.api.client.KeepWebApiClient;
-import org.arvados.client.api.model.Collection;
-import org.arvados.client.common.Characters;
-import org.arvados.client.exception.ArvadosClientException;
-import org.arvados.client.logic.collection.FileToken;
-import org.arvados.client.logic.collection.ManifestDecoder;
-import org.arvados.client.logic.collection.ManifestStream;
-import org.arvados.client.logic.keep.exception.DownloadFolderAlreadyExistsException;
-import org.arvados.client.logic.keep.exception.FileAlreadyExistsException;
-import org.slf4j.Logger;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-public class FileDownloader {
-
-    private final KeepClient keepClient;
-    private final ManifestDecoder manifestDecoder;
-    private final CollectionsApiClient collectionsApiClient;
-    private final KeepWebApiClient keepWebApiClient;
-    private final Logger log = org.slf4j.LoggerFactory.getLogger(FileDownloader.class);
-
-    public FileDownloader(KeepClient keepClient, ManifestDecoder manifestDecoder, CollectionsApiClient collectionsApiClient, KeepWebApiClient keepWebApiClient) {
-        this.keepClient = keepClient;
-        this.manifestDecoder = manifestDecoder;
-        this.collectionsApiClient = collectionsApiClient;
-        this.keepWebApiClient = keepWebApiClient;
-    }
-
-    public List<FileToken> listFileInfoFromCollection(String collectionUuid) {
-        Collection requestedCollection = collectionsApiClient.get(collectionUuid);
-        String manifestText = requestedCollection.getManifestText();
-
-        // decode manifest text and get list of all FileTokens for this collection
-        return manifestDecoder.decode(manifestText)
-                .stream()
-                .flatMap(p -> p.getFileTokens().stream())
-                .collect(Collectors.toList());
-    }
-
-    public File downloadSingleFileUsingKeepWeb(String filePathName, String collectionUuid, String pathToDownloadFolder) {
-        FileToken fileToken = getFileTokenFromCollection(filePathName, collectionUuid);
-        if (fileToken == null) {
-            throw new ArvadosClientException(String.format("%s not found in Collection with UUID %s", filePathName, collectionUuid));
-        }
-
-        File downloadedFile = checkIfFileExistsInTargetLocation(fileToken, pathToDownloadFolder);
-        try (FileOutputStream fos = new FileOutputStream(downloadedFile)) {
-            fos.write(keepWebApiClient.download(collectionUuid, filePathName));
-        } catch (IOException e) {
-            throw new ArvadosClientException(String.format("Unable to write down file %s", fileToken.getFileName()), e);
-        }
-        return downloadedFile;
-    }
-
-    public List<File> downloadFilesFromCollectionUsingKeepWeb(String collectionUuid, String pathToDownloadFolder) {
-        String collectionTargetDir = setTargetDirectory(collectionUuid, pathToDownloadFolder).getAbsolutePath();
-        List<FileToken> fileTokens = listFileInfoFromCollection(collectionUuid);
-
-        List<CompletableFuture<File>> futures = Lists.newArrayList();
-        for (FileToken fileToken : fileTokens) {
-            futures.add(CompletableFuture.supplyAsync(() -> this.downloadOneFileFromCollectionUsingKeepWeb(fileToken, collectionUuid, collectionTargetDir)));
-        }
-
-        @SuppressWarnings("unchecked")
-        CompletableFuture<File>[] array = futures.toArray(new CompletableFuture[0]);
-        return Stream.of(array)
-                .map(CompletableFuture::join).collect(Collectors.toList());
-    }
-
-    private FileToken getFileTokenFromCollection(String filePathName, String collectionUuid) {
-        return listFileInfoFromCollection(collectionUuid)
-                .stream()
-                .filter(p -> (p.getFullPath()).equals(filePathName))
-                .findFirst()
-                .orElse(null);
-    }
-
-    private File checkIfFileExistsInTargetLocation(FileToken fileToken, String pathToDownloadFolder) {
-        String fileName = fileToken.getFileName();
-
-        File downloadFile = new File(pathToDownloadFolder + Characters.SLASH + fileName);
-        if (downloadFile.exists()) {
-            throw new FileAlreadyExistsException(String.format("File %s exists in location %s", fileName, pathToDownloadFolder));
-        } else {
-            return downloadFile;
-        }
-    }
-
-    private File downloadOneFileFromCollectionUsingKeepWeb(FileToken fileToken, String collectionUuid, String pathToDownloadFolder) {
-        String filePathName = fileToken.getPath() + fileToken.getFileName();
-        File downloadedFile = new File(pathToDownloadFolder + Characters.SLASH + filePathName);
-        downloadedFile.getParentFile().mkdirs();
-
-        try (FileOutputStream fos = new FileOutputStream(downloadedFile)) {
-            fos.write(keepWebApiClient.download(collectionUuid, filePathName));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        return downloadedFile;
-    }
-
-    public List<File> downloadFilesFromCollection(String collectionUuid, String pathToDownloadFolder) {
-
-        // download requested collection and extract manifest text
-        Collection requestedCollection = collectionsApiClient.get(collectionUuid);
-        String manifestText = requestedCollection.getManifestText();
-
-        // if directory with this collectionUUID does not exist - create one
-        // if exists - abort (throw exception)
-        File collectionTargetDir = setTargetDirectory(collectionUuid, pathToDownloadFolder);
-
-        // decode manifest text and create list of ManifestStream objects containing KeepLocators and FileTokens
-        List<ManifestStream> manifestStreams = manifestDecoder.decode(manifestText);
-
-        //list of all downloaded files that will be returned by this method
-        List<File> downloadedFilesFromCollection = new ArrayList<>();
-
-        // download files for each manifest stream
-        for (ManifestStream manifestStream : manifestStreams)
-            downloadedFilesFromCollection.addAll(downloadFilesFromSingleManifestStream(manifestStream, collectionTargetDir));
-
-        log.debug(String.format("Total of: %d files downloaded", downloadedFilesFromCollection.size()));
-        return downloadedFilesFromCollection;
-    }
-
-    private File setTargetDirectory(String collectionUUID, String pathToDownloadFolder) {
-        //local directory to save downloaded files
-        File collectionTargetDir = new File(pathToDownloadFolder + Characters.SLASH + collectionUUID);
-        if (collectionTargetDir.exists()) {
-            throw new DownloadFolderAlreadyExistsException(String.format("Directory for collection UUID %s already exists", collectionUUID));
-        } else {
-            collectionTargetDir.mkdirs();
-        }
-        return collectionTargetDir;
-    }
-
-    private List<File> downloadFilesFromSingleManifestStream(ManifestStream manifestStream, File collectionTargetDir){
-        List<File> downloadedFiles = new ArrayList<>();
-        List<KeepLocator> keepLocators = manifestStream.getKeepLocators();
-        DownloadHelper downloadHelper = new DownloadHelper(keepLocators);
-
-        for (FileToken fileToken : manifestStream.getFileTokens()) {
-            File downloadedFile = new File(collectionTargetDir.getAbsolutePath() + Characters.SLASH + fileToken.getFullPath()); //create file
-            downloadedFile.getParentFile().mkdirs();
-
-            try (FileOutputStream fos = new FileOutputStream(downloadedFile, true)) {
-                downloadHelper.setBytesToDownload(fileToken.getFileSize()); //update file size info
-
-                //this part needs to be repeated for each file until whole file is downloaded
-                do {
-                    downloadHelper.requestNewDataChunk(); //check if new data chunk needs to be downloaded
-                    downloadHelper.writeDownFile(fos); // download data from chunk
-                } while (downloadHelper.getBytesToDownload() != 0);
-
-            } catch (IOException | ArvadosClientException e) {
-                throw new ArvadosClientException(String.format("Unable to write down file %s", fileToken.getFileName()), e);
-            }
-
-            downloadedFiles.add(downloadedFile);
-            log.debug(String.format("File %d / %d downloaded from manifest stream",
-                    manifestStream.getFileTokens().indexOf(fileToken) + 1,
-                    manifestStream.getFileTokens().size()));
-        }
-        return downloadedFiles;
-    }
-
-    private class DownloadHelper {
-
-        // values for tracking file output streams and matching data chunks with initial files
-        int currentDataChunkNumber;
-        int bytesDownloadedFromChunk;
-        int bytesToDownload;
-        byte[] currentDataChunk;
-        boolean remainingDataInChunk;
-        final List<KeepLocator> keepLocators;
-
-        private DownloadHelper(List<KeepLocator> keepLocators) {
-            currentDataChunkNumber = -1;
-            bytesDownloadedFromChunk = 0;
-            remainingDataInChunk = false;
-            this.keepLocators = keepLocators;
-        }
-
-        private int getBytesToDownload() {
-            return bytesToDownload;
-        }
-
-        private void setBytesToDownload(int bytesToDownload) {
-            this.bytesToDownload = bytesToDownload;
-        }
-
-        private void requestNewDataChunk() {
-            if (!remainingDataInChunk) {
-                currentDataChunkNumber++;
-                if (currentDataChunkNumber < keepLocators.size()) {
-                    //swap data chunk for next one
-                    currentDataChunk = keepClient.getDataChunk(keepLocators.get(currentDataChunkNumber));
-                    log.debug(String.format("%d of %d data chunks from manifest stream downloaded", currentDataChunkNumber + 1, keepLocators.size()));
-                } else {
-                    throw new ArvadosClientException("Data chunk required for download is missing.");
-                }
-            }
-        }
-
-        private void writeDownFile(FileOutputStream fos) throws IOException {
-            //case 1: more bytes needed than available in current chunk (or whole current chunk needed) to download file
-            if (bytesToDownload >= currentDataChunk.length - bytesDownloadedFromChunk) {
-                writeDownWholeDataChunk(fos);
-            }
-            //case 2: current data chunk contains more bytes than is needed for this file
-            else {
-                writeDownDataChunkPartially(fos);
-            }
-        }
-
-        private void writeDownWholeDataChunk(FileOutputStream fos) throws IOException {
-            // write all remaining bytes from current chunk
-            fos.write(currentDataChunk, bytesDownloadedFromChunk, currentDataChunk.length - bytesDownloadedFromChunk);
-            //update bytesToDownload
-            bytesToDownload -= (currentDataChunk.length - bytesDownloadedFromChunk);
-            // set remaining data in chunk to false
-            remainingDataInChunk = false;
-            //reset bytesDownloadedFromChunk so that its set to 0 for the next chunk
-            bytesDownloadedFromChunk = 0;
-        }
-
-        private void writeDownDataChunkPartially(FileOutputStream fos) throws IOException {
-            //write all remaining bytes for this file from current chunk
-            fos.write(currentDataChunk, bytesDownloadedFromChunk, bytesToDownload);
-            // update number of bytes downloaded from this chunk
-            bytesDownloadedFromChunk += bytesToDownload;
-            // set remaining data in chunk to true
-            remainingDataInChunk = true;
-            // reset bytesToDownload to exit while loop and move to the next file
-            bytesToDownload = 0;
-        }
-    }
-}
\ No newline at end of file