Replace files
authorszlenkj <jakub.szlenk@contractors.roche.com>
Mon, 5 Feb 2024 12:49:30 +0000 (13:49 +0100)
committerszlenkj <jakub.szlenk@contractors.roche.com>
Fri, 9 Feb 2024 09:38:30 +0000 (10:38 +0100)
Arvados-DCO-1.1-Signed-off-by: Jakub Szlenk jakubszlenk@gmail.com

sdk/java-v2/src/main/java/org/arvados/client/api/client/BaseStandardApiClient.java
sdk/java-v2/src/main/java/org/arvados/client/api/client/CollectionsApiClient.java
sdk/java-v2/src/main/java/org/arvados/client/api/model/CollectionReplaceFiles.java [new file with mode: 0644]
sdk/java-v2/src/main/java/org/arvados/client/facade/ArvadosFacade.java
sdk/java-v2/src/test/java/org/arvados/client/api/client/CollectionsApiClientTest.java

index ab03d34f19b1e0d1e8714edf3dfca186b2efbc12..4bd59a75d7e0084e4429af13d054bb13d37db67a 100644 (file)
@@ -27,7 +27,7 @@ import java.util.Map;
 
 public abstract class BaseStandardApiClient<T extends Item, L extends ItemList> extends BaseApiClient {
 
-    private static final MediaType JSON = MediaType.parse(com.google.common.net.MediaType.JSON_UTF_8.toString());
+    protected static final MediaType JSON = MediaType.parse(com.google.common.net.MediaType.JSON_UTF_8.toString());
     private final Logger log = org.slf4j.LoggerFactory.getLogger(BaseStandardApiClient.class);
 
     BaseStandardApiClient(ConfigProvider config) {
@@ -107,7 +107,7 @@ public abstract class BaseStandardApiClient<T extends Item, L extends ItemList>
         return MAPPER.readValue(content, cls);
     }
 
-    private <TL> String mapToJson(TL type) {
+    protected  <TL> String mapToJson(TL type) {
         ObjectWriter writer = MAPPER.writer().withDefaultPrettyPrinter();
         try {
             return writer.writeValueAsString(type);
index 141f02deba38e6227e0c6b24ef881fd5cdae422a..581253f53cd2cf1fbb2d6b96aa9f7e616cac1fcb 100644 (file)
@@ -9,12 +9,18 @@ package org.arvados.client.api.client;
 
 import org.arvados.client.api.model.Collection;
 import org.arvados.client.api.model.CollectionList;
+import org.arvados.client.api.model.CollectionReplaceFiles;
 import org.arvados.client.config.ConfigProvider;
 import org.slf4j.Logger;
 
+import okhttp3.HttpUrl;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
 public class CollectionsApiClient extends BaseStandardApiClient<Collection, CollectionList> {
 
     private static final String RESOURCE = "collections";
+
     private final Logger log = org.slf4j.LoggerFactory.getLogger(CollectionsApiClient.class);
 
     public CollectionsApiClient(ConfigProvider config) {
@@ -28,6 +34,14 @@ public class CollectionsApiClient extends BaseStandardApiClient<Collection, Coll
         return newCollection;
     }
 
+    public Collection update(String collectionUUID, CollectionReplaceFiles replaceFilesRequest) {
+        String json = mapToJson(replaceFilesRequest);
+        RequestBody body = RequestBody.create(JSON, json);
+        HttpUrl url = getUrlBuilder().addPathSegment(collectionUUID).build();
+        Request request = getRequestBuilder().put(body).url(url).build();
+        return callForType(request);
+    }
+
     @Override
     String getResource() {
         return RESOURCE;
diff --git a/sdk/java-v2/src/main/java/org/arvados/client/api/model/CollectionReplaceFiles.java b/sdk/java-v2/src/main/java/org/arvados/client/api/model/CollectionReplaceFiles.java
new file mode 100644 (file)
index 0000000..2ef19ce
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) The Arvados Authors. All rights reserved.
+ *
+ * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
+ *
+ */
+
+package org.arvados.client.api.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CollectionReplaceFiles {
+
+    @JsonProperty("collection")
+    private CollectionOptions collectionOptions;
+
+    @JsonProperty("replace_files")
+    private Map<String, String> replaceFiles;
+
+    public CollectionReplaceFiles() {
+        this.collectionOptions = new CollectionOptions();
+        this.replaceFiles = new HashMap<>();
+    }
+
+    public void addFileReplacement(String targetPath, String sourcePath) {
+        this.replaceFiles.put(targetPath, sourcePath);
+    }
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class CollectionOptions {
+        @JsonProperty("preserve_version")
+        private boolean preserveVersion;
+
+        public CollectionOptions() {
+            this.preserveVersion = true;
+        }
+
+        public boolean isPreserveVersion() {
+            return preserveVersion;
+        }
+
+        public void setPreserveVersion(boolean preserveVersion) {
+            this.preserveVersion = preserveVersion;
+        }
+    }
+
+    public CollectionOptions getCollectionOptions() {
+        return collectionOptions;
+    }
+
+    public void setCollectionOptions(CollectionOptions collectionOptions) {
+        this.collectionOptions = collectionOptions;
+    }
+
+    public Map<String, String> getReplaceFiles() {
+        return replaceFiles;
+    }
+
+    public void setReplaceFiles(Map<String, String> replaceFiles) {
+        this.replaceFiles = replaceFiles;
+    }
+}
\ No newline at end of file
index 571cb2590906f9d041a342dbf26d95724184e3b0..8b65cebc59a0d20d0c9ba1b6add34aaf65e2a584 100644 (file)
@@ -28,6 +28,7 @@ import java.io.File;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 public class ArvadosFacade {
 
@@ -201,6 +202,21 @@ public class ArvadosFacade {
         return collectionsApiClient.create(collection);
     }
 
+    /**
+     * Uploads multiple files to an existing collection.
+     *
+     * @param collectionUUID UUID of collection to which the files are to be copied
+     * @param files          map of files to be copied to existing collection.
+     *                       The map consists of a pair in the form of a filename and a filename
+     *                       along with the Portable data hash
+     * @return collection object mapped from JSON that is returned from server after successful copied
+     */
+    public Collection updateWithReplaceFiles(String collectionUUID, Map<String, String> files) {
+        CollectionReplaceFiles replaceFilesRequest = new CollectionReplaceFiles();
+        replaceFilesRequest.getReplaceFiles().putAll(files);
+        return collectionsApiClient.update(collectionUUID, replaceFilesRequest);
+    }
+
     /**
      * Returns current user information based on Api Token provided via configuration
      *
index 8da3bfbf514b04c6f188bb0f5e1185d42c8002d9..94a79041a0f135bb997ec9b3704d29eb58811bfd 100644 (file)
@@ -7,21 +7,39 @@
 
 package org.arvados.client.api.client;
 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
 import okhttp3.mockwebserver.RecordedRequest;
 import org.arvados.client.api.model.Collection;
 import org.arvados.client.api.model.CollectionList;
+import org.arvados.client.api.model.CollectionReplaceFiles;
 import org.arvados.client.test.utils.RequestMethod;
 import org.arvados.client.test.utils.ArvadosClientMockedWebServerTest;
+import org.junit.Before;
 import org.junit.Test;
 
 import static org.arvados.client.test.utils.ApiClientTestUtils.*;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
 
 public class CollectionsApiClientTest extends ArvadosClientMockedWebServerTest {
 
     private static final String RESOURCE = "collections";
-
-    private CollectionsApiClient client = new CollectionsApiClient(CONFIG);
+    private static final String TEST_COLLECTION_NAME = "Super Collection";
+    private static final String TEST_COLLECTION_UUID = "test-collection-uuid";
+    private ObjectMapper objectMapper;
+    private CollectionsApiClient client;
+
+    @Before
+    public void setUp() {
+        objectMapper = new ObjectMapper();
+        objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+        client = new CollectionsApiClient(CONFIG);
+    }
 
     @Test
     public void listCollections() throws Exception {
@@ -66,7 +84,7 @@ public class CollectionsApiClientTest extends ArvadosClientMockedWebServerTest {
         // given
         server.enqueue(getResponse("collections-create-simple"));
 
-        String name = "Super Collection";
+        String name = TEST_COLLECTION_NAME;
         
         Collection collection = new Collection();
         collection.setName(name);
@@ -90,7 +108,7 @@ public class CollectionsApiClientTest extends ArvadosClientMockedWebServerTest {
         // given
         server.enqueue(getResponse("collections-create-manifest"));
 
-        String name = "Super Collection";
+        String name = TEST_COLLECTION_NAME;
         String manifestText = ". 7df44272090cee6c0732382bba415ee9+70+Aa5ece4560e3329315165b36c239b8ab79c888f8a@5a1d5708 0:70:README.md\n";
         
         Collection collection = new Collection();
@@ -109,4 +127,45 @@ public class CollectionsApiClientTest extends ArvadosClientMockedWebServerTest {
         assertThat(actual.getPortableDataHash()).isEqualTo("d41d8cd98f00b204e9800998ecf8427e+0");
         assertThat(actual.getManifestText()).isEqualTo(manifestText);
     }
+
+    @Test
+    public void testUpdateWithReplaceFiles() throws IOException, InterruptedException {
+        // given
+        server.enqueue(getResponse("collections-create-manifest"));
+
+        Map<String, String> files = new HashMap<>();
+        files.put("targetPath1", "sourcePath1");
+        files.put("targetPath2", "sourcePath2");
+
+        CollectionReplaceFiles replaceFilesRequest = new CollectionReplaceFiles();
+        replaceFilesRequest.setReplaceFiles(files);
+
+        // when
+        Collection actual = client.update(TEST_COLLECTION_UUID, replaceFilesRequest);
+
+        // then
+        RecordedRequest request = server.takeRequest();
+        assertAuthorizationHeader(request);
+        assertRequestPath(request, "collections/test-collection-uuid");
+        assertRequestMethod(request, RequestMethod.PUT);
+        assertThat(actual.getPortableDataHash()).isEqualTo("d41d8cd98f00b204e9800998ecf8427e+0");
+
+        String actualRequestBody = request.getBody().readUtf8();
+        Map<String, Object> actualRequestMap = objectMapper.readValue(actualRequestBody, Map.class);
+
+        Map<String, Object> expectedRequestMap = new HashMap<>();
+        Map<String, Object> collectionOptionsMap = new HashMap<>();
+        collectionOptionsMap.put("preserve_version", true);
+
+        Map<String, String> replaceFilesMap = new HashMap<>();
+        replaceFilesMap.put("targetPath1", "sourcePath1");
+        replaceFilesMap.put("targetPath2", "sourcePath2");
+
+        expectedRequestMap.put("collection", collectionOptionsMap);
+        expectedRequestMap.put("replace_files", replaceFilesMap);
+
+        String expectedJson = objectMapper.writeValueAsString(expectedRequestMap);
+        String actualJson = objectMapper.writeValueAsString(actualRequestMap);
+        assertEquals(expectedJson, actualJson);
+    }
 }