diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e742828c..f212106c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
# Changelog
+## 7.8.0 (2021-06-22)
+
+## 增加
+* 支持批量解冻归档
## 7.7.0 (2021-05-28)
diff --git a/README.md b/README.md
index f963efec4..cf2d29fec 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,12 @@
com.qiniu
qiniu-java-sdk
- [7.7.0, 7.7.99]
+ [7.8.0, 7.8.99]
```
或者 Gradle:
```groovy
-compile 'com.qiniu:qiniu-java-sdk:7.7.+'
+compile 'com.qiniu:qiniu-java-sdk:7.8.+'
```
## 运行环境
diff --git a/build.gradle b/build.gradle
index 682842f65..e4f520146 100755
--- a/build.gradle
+++ b/build.gradle
@@ -13,11 +13,11 @@ repositories {
}
jacocoTestReport {
- reports {
- xml.enabled true
- html.enabled false
- }
- }
+ reports {
+ xml.enabled true
+ html.enabled false
+ }
+}
dependencies {
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.4'
diff --git a/src/main/java/com/qiniu/common/Constants.java b/src/main/java/com/qiniu/common/Constants.java
index 631208146..616753b3a 100644
--- a/src/main/java/com/qiniu/common/Constants.java
+++ b/src/main/java/com/qiniu/common/Constants.java
@@ -9,7 +9,7 @@ public final class Constants {
/**
* 版本号
*/
- public static final String VERSION = "7.7.0";
+ public static final String VERSION = "7.8.0";
/**
* 块大小,不能改变
*/
diff --git a/src/main/java/com/qiniu/storage/BucketManager.java b/src/main/java/com/qiniu/storage/BucketManager.java
index 60ecbc0a9..1e6107281 100644
--- a/src/main/java/com/qiniu/storage/BucketManager.java
+++ b/src/main/java/com/qiniu/storage/BucketManager.java
@@ -1207,6 +1207,22 @@ public BatchOperations addDeleteAfterDaysOps(String bucket, int days, String...
return this;
}
+ /**
+ * 添加解冻归档存储指令
+ *
+ * @param bucket keys 所在 bucket
+ * @param freezeAfterDays 解冻有效时长,取值范围 1~7
+ * @param keys keys
+ * @return BatchOperations
+ */
+ public BatchOperations addRestoreArchiveOps(String bucket, int freezeAfterDays, String... keys) {
+ for (String key : keys) {
+ ops.add(String.format("restoreAr/%s/freezeAfterDays/%d", encodedEntry(bucket, key), freezeAfterDays));
+ }
+ setExecBucket(bucket);
+ return this;
+ }
+
public byte[] toBody() {
String body = StringUtils.join(ops, "&op=", "op=");
return StringUtils.utf8Bytes(body);
diff --git a/src/test/java/test/com/qiniu/storage/BucketTest.java b/src/test/java/test/com/qiniu/storage/BucketTest.java
index c1cc0454d..09e1bf794 100644
--- a/src/test/java/test/com/qiniu/storage/BucketTest.java
+++ b/src/test/java/test/com/qiniu/storage/BucketTest.java
@@ -1559,6 +1559,129 @@ public void testFile(TestConfig.TestFile file, BucketManager bucketManager) thro
});
}
+ @Test
+ public void testBatchRestoreArchive() throws Exception {
+
+ testFileWithHandler(new TestFileHandler() {
+ @Override
+ public void testFile(TestConfig.TestFile file, BucketManager bucketManager) throws IOException {
+ String bucket = file.getBucketName();
+ String key = file.getKey();
+ String keyToTestPrefix = "batch_restore_archive";
+
+ BucketManager.BatchOperations deleteOps = new BucketManager.BatchOperations();
+ try {
+ List keys = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ keys.add(keyToTestPrefix + "_" + i);
+ }
+
+ for (String keyToTest : keys) {
+ // if stat, delete
+ try {
+ Response resp = bucketManager.statResponse(bucket, keyToTest);
+ if (resp.statusCode == 200) bucketManager.delete(bucket, keyToTest);
+ } catch (QiniuException ex) {
+ System.out.println("file " + keyToTest + " not exists, ok.");
+ }
+ }
+
+ // copy and changeType to Archive
+ BucketManager.BatchOperations copyOps = new BucketManager.BatchOperations();
+ BucketManager.BatchOperations copyAfterArchiveOps = new BucketManager.BatchOperations();
+ BucketManager.BatchOperations changeTypeOps = new BucketManager.BatchOperations();
+ BucketManager.BatchOperations restoreArchiveOps = new BucketManager.BatchOperations();
+ for (String keyToTest : keys) {
+ copyOps.addCopyOp(bucket, key, bucket, keyToTest);
+ copyAfterArchiveOps.addCopyOp(bucket, keyToTest, bucket, keyToTest + "_copy");
+ deleteOps.addDeleteOp(bucket, keyToTest, keyToTest + "_copy");
+ changeTypeOps.addChangeTypeOps(bucket, StorageType.Archive, keyToTest);
+ restoreArchiveOps.addRestoreArchiveOps(bucket, 1, keyToTest);
+ }
+ Response copyResponse = bucketManager.batch(copyOps);
+ Assert.assertEquals(200, copyResponse.statusCode);
+
+ Response changeTypeResponse = bucketManager.batch(changeTypeOps);
+ Assert.assertEquals(200, changeTypeResponse.statusCode);
+
+ // 验证归档不可 copy
+ try {
+ Response copyAfterArchiveResponse = bucketManager.batch(copyAfterArchiveOps);
+ String bodyString = copyAfterArchiveResponse.bodyString();
+ Assert.assertNotEquals(200, "batch copy can't be success" + bodyString);
+ } catch (QiniuException ex) {
+ Assert.assertEquals(400, ex.response.statusCode);
+ System.out.println(ex.response.bodyString());
+ }
+
+ // restoreArchive
+ Response restoreResponse = bucketManager.batch(restoreArchiveOps);
+ String bodyString = restoreResponse.bodyString();
+ System.out.println(bodyString);
+ Assert.assertEquals(200, restoreResponse.statusCode);
+
+ //test for 400 Bad Request {"error":"invalid freeze after days"}
+ try {
+ restoreResponse = bucketManager.batch(restoreArchiveOps);
+ bodyString = restoreResponse.bodyString();
+ System.out.println(bodyString);
+ } catch (QiniuException ex) {
+ Assert.assertEquals(400, ex.response.statusCode);
+ System.out.println(ex.response.bodyString());
+ }
+
+ long checkStart = new Date().getTime();
+ boolean shouldCheck = true;
+ boolean success = false;
+ while (shouldCheck) {
+ // 验证解归档可 copy
+ try {
+ Response copyAfterArchiveResponse = bucketManager.batch(copyAfterArchiveOps);
+ bodyString = copyAfterArchiveResponse.bodyString();
+ System.out.println(bodyString);
+ // 可以 copy 但文件已存在
+ if (bodyString.contains("\"code\":614")) {
+ success = true;
+ break;
+ }
+ } catch (QiniuException ex) {
+ System.out.println(ex.response.bodyString());
+ if (ex.response.statusCode == 400) {
+ success = true;
+ break;
+ }
+ }
+
+ long current = new Date().getTime();
+ if (current - checkStart > 1000 * 60 * 5.5) {
+ shouldCheck = false;
+ }
+
+ try {
+ Thread.sleep(1000 * 10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ Assert.assertTrue("can copy after restore archive", success);
+ } catch (QiniuException e) {
+ Assert.fail(bucket + ":" + key + " > " + keyToTestPrefix + " >> " + e.response.toString());
+ } finally {
+ try {
+ Response response = bucketManager.batch(deleteOps);
+ String bodyString = response.bodyString();
+ System.out.println(bodyString);
+ Assert.assertTrue(bodyString, response.statusCode == 200 || response.statusCode == 298);
+ } catch (QiniuException ex) {
+ Assert.assertEquals(400, ex.response.statusCode);
+ System.out.println(ex.response.bodyString());
+ }
+ }
+ }
+ });
+ }
+
/**
* 测试noIndexPage
*