Skip to content

Commit 8a3c757

Browse files
authored
Support download backup version api
1 parent 9e91064 commit 8a3c757

File tree

4 files changed

+132
-1
lines changed

4 files changed

+132
-1
lines changed

cloudinary-core/src/main/java/com/cloudinary/Api.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public ApiResponse resource(String public_id, Map options) throws Exception {
141141
ApiResponse response = callApi(HttpMethod.GET, Arrays.asList("resources", resourceType, type, public_id),
142142
ObjectUtils.only(options, "exif", "colors", "faces", "coordinates",
143143
"image_metadata", "pages", "phash", "max_results", "quality_analysis", "cinemagraph_analysis",
144-
"accessibility_analysis"), options);
144+
"accessibility_analysis", "versions"), options);
145145

146146
return response;
147147
}
@@ -302,6 +302,7 @@ public ApiResponse restore(Iterable<String> publicIds, Map options) throws Excep
302302
String type = ObjectUtils.asString(options.get("type"), "upload");
303303
Map params = new HashMap<String, Object>();
304304
params.put("public_ids", publicIds);
305+
params.put("versions", options.get("versions"));
305306

306307
ApiResponse response = callApi(HttpMethod.POST, Arrays.asList("resources", resourceType, type, "restore"), params, options);
307308
return response;

cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,34 @@ public String downloadFolder(String folderPath, Map options) throws UnsupportedE
338338
return downloadArchive(adjustedOptions, (String) adjustedOptions.get("target_format"));
339339
}
340340

341+
/**
342+
* Returns an URL of a specific version of a backed up asset that can be used to download that
343+
* version of the asset (within an hour of the request).
344+
*
345+
* @param assetId The identifier of the uploaded asset.
346+
* @param versionId The identifier of a backed up version of the asset.
347+
* @param options Optional, holds hints for URL generation procedure, see documentation for
348+
* full list
349+
* @return The download URL of the asset
350+
*/
351+
public String downloadBackedupAsset(String assetId, String versionId, Map options) throws UnsupportedEncodingException {
352+
if (StringUtils.isEmpty(assetId)) {
353+
throw new IllegalArgumentException("AssetId parameter is required");
354+
}
355+
356+
if (StringUtils.isEmpty(versionId)) {
357+
throw new IllegalArgumentException("VersionId parameter is required");
358+
}
359+
360+
Map<String, Object> params = new HashMap<String, Object>();
361+
params.put("asset_id", assetId);
362+
params.put("version_id", versionId);
363+
params.put("timestamp", Util.timestamp());
364+
365+
signRequest(params, options);
366+
return buildUrl(cloudinaryApiUrl("download_backup", options), params);
367+
}
368+
341369
private String buildUrl(String base, Map<String, Object> params) throws UnsupportedEncodingException {
342370
StringBuilder urlBuilder = new StringBuilder();
343371
urlBuilder.append(base);

cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.lang.reflect.Modifier;
2020
import java.lang.reflect.Type;
2121
import java.net.URI;
22+
import java.net.URISyntaxException;
2223
import java.net.URLDecoder;
2324
import java.net.URLEncoder;
2425
import java.util.*;
@@ -1405,6 +1406,21 @@ public void testApiSignRequestSHA256() {
14051406
assertEquals("45ddaa4fa01f0c2826f32f669d2e4514faf275fe6df053f1a150e7beae58a3bd", signature);
14061407
}
14071408

1409+
@Test
1410+
public void testDownloadBackedupAsset() throws UnsupportedEncodingException, URISyntaxException {
1411+
String url = cloudinary.downloadBackedupAsset("62c2a18d622be7e190d21df8e05b1416",
1412+
"26fe6d95df856f6ae12f5678be94516a", ObjectUtils.emptyMap());
1413+
1414+
URI uri = new URI(url);
1415+
assertTrue(uri.getPath().endsWith("download_backup"));
1416+
1417+
Map params = getUrlParameters(uri);
1418+
assertEquals("62c2a18d622be7e190d21df8e05b1416", params.get("asset_id"));
1419+
assertEquals("26fe6d95df856f6ae12f5678be94516a", params.get("version_id"));
1420+
assertNotNull(params.get("signature"));
1421+
assertNotNull(params.get("timestamp"));
1422+
}
1423+
14081424
private void assertFieldsEqual(Object a, Object b) throws IllegalAccessException {
14091425
assertEquals("Two objects must be the same class", a.getClass(), b.getClass());
14101426
Field[] fields = a.getClass().getFields();

cloudinary-test-common/src/main/java/com/cloudinary/test/AbstractApiTest.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,92 @@ public void testRestore() throws Exception {
829829
assertEquals(resource.get("bytes"), 3381);
830830
}
831831

832+
@Test
833+
public void testRestoreDifferentVersionsOfDeletedAsset() throws Exception {
834+
final String TEST_RESOURCE_PUBLIC_ID = "api_test_restore_different_versions_single_asset" + SUFFIX;
835+
final Uploader uploader = cloudinary.uploader();
836+
837+
Map firstUpload = uploader.upload(SRC_TEST_IMAGE,
838+
ObjectUtils.asMap(
839+
"public_id", TEST_RESOURCE_PUBLIC_ID,
840+
"backup", true,
841+
"tags", UPLOAD_TAGS
842+
));
843+
assertEquals(firstUpload.get("public_id"), TEST_RESOURCE_PUBLIC_ID);
844+
ApiResponse firstDelete = api.deleteResources(Collections.singletonList(TEST_RESOURCE_PUBLIC_ID), ObjectUtils.emptyMap());
845+
assertTrue(firstDelete.containsKey("deleted"));
846+
847+
Map secondUpload = uploader.upload(SRC_TEST_IMAGE,
848+
ObjectUtils.asMap(
849+
"public_id", TEST_RESOURCE_PUBLIC_ID,
850+
"backup", true,
851+
"transformation", new Transformation().angle("0"),
852+
"tags", UPLOAD_TAGS
853+
));
854+
assertEquals(secondUpload.get("public_id"), TEST_RESOURCE_PUBLIC_ID);
855+
ApiResponse secondDelete = api.deleteResources(Collections.singletonList(TEST_RESOURCE_PUBLIC_ID), ObjectUtils.emptyMap());
856+
assertTrue(secondDelete.containsKey("deleted"));
857+
858+
assertNotEquals(firstUpload.get("bytes"), secondUpload.get("bytes"));
859+
860+
ApiResponse getVersionsResp = api.resource(TEST_RESOURCE_PUBLIC_ID, ObjectUtils.asMap("versions", true));
861+
List<Map> versions = (List<Map>) getVersionsResp.get("versions");
862+
Object firstAssetVersion = versions.get(0).get("version_id");
863+
Object secondAssetVersion = versions.get(1).get("version_id");
864+
865+
ApiResponse firstVerRestore = api.restore(Collections.singletonList(TEST_RESOURCE_PUBLIC_ID),
866+
ObjectUtils.asMap("versions", Collections.singletonList(firstAssetVersion)));
867+
assertEquals(((Map) firstVerRestore.get(TEST_RESOURCE_PUBLIC_ID)).get("bytes"), firstUpload.get("bytes"));
868+
869+
ApiResponse secondVerRestore = api.restore(Collections.singletonList(TEST_RESOURCE_PUBLIC_ID),
870+
ObjectUtils.asMap("versions", Collections.singletonList(secondAssetVersion)));
871+
assertEquals(((Map) secondVerRestore.get(TEST_RESOURCE_PUBLIC_ID)).get("bytes"), secondUpload.get("bytes"));
872+
873+
ApiResponse finalDeleteResp = api.deleteResources(Collections.singletonList(TEST_RESOURCE_PUBLIC_ID), ObjectUtils.emptyMap());
874+
assertTrue(finalDeleteResp.containsKey("deleted"));
875+
}
876+
877+
@Test
878+
public void testShouldRestoreTwoDifferentDeletedAssets() throws Exception {
879+
final String PUBLIC_ID_BACKUP_1 = "api_test_restore_versions_different_assets_1_" + SUFFIX;
880+
final String PUBLIC_ID_BACKUP_2 = "api_test_restore_versions_different_assets_2_" + SUFFIX;
881+
882+
final Uploader uploader = cloudinary.uploader();
883+
884+
Map firstUpload = uploader.upload(SRC_TEST_IMAGE,
885+
ObjectUtils.asMap(
886+
"public_id", PUBLIC_ID_BACKUP_1,
887+
"backup", true,
888+
"tags", UPLOAD_TAGS
889+
));
890+
Map secondUpload = uploader.upload(SRC_TEST_IMAGE,
891+
ObjectUtils.asMap(
892+
"public_id", PUBLIC_ID_BACKUP_2,
893+
"backup", true,
894+
"transformation", new Transformation().angle("0"),
895+
"tags", UPLOAD_TAGS
896+
));
897+
898+
ApiResponse deleteAll = api.deleteResources(Arrays.asList(PUBLIC_ID_BACKUP_1, PUBLIC_ID_BACKUP_2), ObjectUtils.emptyMap());
899+
assertEquals("deleted", ((Map) deleteAll.get("deleted")).get(PUBLIC_ID_BACKUP_1));
900+
assertEquals("deleted", ((Map) deleteAll.get("deleted")).get(PUBLIC_ID_BACKUP_2));
901+
902+
ApiResponse getFirstAssetVersion = api.resource(PUBLIC_ID_BACKUP_1, ObjectUtils.asMap("versions", true));
903+
ApiResponse getSecondAssetVersion = api.resource(PUBLIC_ID_BACKUP_2, ObjectUtils.asMap("versions", true));
904+
905+
Object firstAssetVersion = ((List<Map>) getFirstAssetVersion.get("versions")).get(0).get("version_id");
906+
Object secondAssetVersion = ((List<Map>) getSecondAssetVersion.get("versions")).get(0).get("version_id");
907+
908+
ApiResponse restore = api.restore(Arrays.asList(PUBLIC_ID_BACKUP_1, PUBLIC_ID_BACKUP_2),
909+
ObjectUtils.asMap("versions", Arrays.asList(firstAssetVersion, secondAssetVersion)));
910+
assertEquals(((Map) restore.get(PUBLIC_ID_BACKUP_1)).get("bytes"), firstUpload.get("bytes"));
911+
assertEquals(((Map) restore.get(PUBLIC_ID_BACKUP_2)).get("bytes"), secondUpload.get("bytes"));
912+
913+
ApiResponse finalDelete = api.deleteResources(Arrays.asList(PUBLIC_ID_BACKUP_1, PUBLIC_ID_BACKUP_2), ObjectUtils.emptyMap());
914+
assertEquals("deleted", ((Map) finalDelete.get("deleted")).get(PUBLIC_ID_BACKUP_1));
915+
assertEquals("deleted", ((Map) finalDelete.get("deleted")).get(PUBLIC_ID_BACKUP_2));
916+
}
917+
832918
@Test
833919
public void testEncodeUrlInApiCall() throws Exception {
834920
String apiTestEncodeUrlInApiCall = "sub^folder test";

0 commit comments

Comments
 (0)