Skip to content

Commit f784a07

Browse files
authored
Batch more params (#596)
1 parent ac4d1fd commit f784a07

File tree

5 files changed

+366
-26
lines changed

5 files changed

+366
-26
lines changed

src/main/java/com/qiniu/storage/BucketManager.java

Lines changed: 171 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,15 +1251,53 @@ public BatchOperations() {
12511251
* @return BatchOperations
12521252
*/
12531253
public BatchOperations addChgmOp(String bucket, String key, String newMimeType) {
1254-
String resource = encodedEntry(bucket, key);
1255-
String encodedMime = UrlSafeBase64.encodeToString(newMimeType);
1256-
ops.add(String.format("/chgm/%s/mime/%s", resource, encodedMime));
1254+
return addChgmOp(bucket, key, newMimeType, null, null);
1255+
}
1256+
1257+
/**
1258+
* 添加 chgm 指令
1259+
* <a href="http://developer.qiniu.com/kodo/api/chgm"> 相关链接 </a>
1260+
* newMimeType 和 metaData 必须有其一
1261+
*
1262+
* @param bucket 空间名
1263+
* @param key 文件的 key
1264+
* @param newMimeType 修改后的 MimeType [可选]
1265+
* @param metas 需要修改的 metas,只包含需要更改的 metas,可增加 [可选]
1266+
* 服务接口中 key 必须包含 x-qn-meta- 前缀,SDK 会对 metas 中的 key 进行检测
1267+
* - key 如果包含了 x-qn-meta- 前缀,则直接使用 key
1268+
* - key 如果不包含了 x-qn-meta- 前缀,则内部会为 key 拼接 x-qn-meta- 前缀
1269+
* @param condition 自定义条件信息;只有条件匹配才会执行修改操作 [可选]
1270+
* @return BatchOperations
1271+
*/
1272+
public BatchOperations addChgmOp(String bucket, String key, String newMimeType, Map<String, String> metas, Condition condition) {
1273+
StringBuilder builder = new StringBuilder()
1274+
.append("/chgm/").append(encodedEntry(bucket, key));
1275+
if (newMimeType != null && !newMimeType.isEmpty()) {
1276+
builder.append("/mime/").append(UrlSafeBase64.encodeToString(newMimeType));
1277+
}
1278+
1279+
if (metas != null) {
1280+
for (String k : metas.keySet()) {
1281+
if (k.startsWith("x-qn-meta-")) {
1282+
builder.append("/").append(k);
1283+
} else {
1284+
builder.append("/x-qn-meta-").append(k);
1285+
}
1286+
builder.append("/").append(UrlSafeBase64.encodeToString(metas.get(k)));
1287+
}
1288+
}
1289+
1290+
if (condition != null && condition.encodedString() != null) {
1291+
builder.append("/cond/").append(condition.encodedString());
1292+
}
1293+
ops.add(builder.toString());
12571294
setExecBucket(bucket);
12581295
return this;
12591296
}
12601297

12611298
/**
12621299
* 添加 copy 指令
1300+
* 如果目标文件名已被占用,则返回错误码 614,且不做任何覆盖操作;
12631301
*
12641302
* @param fromBucket 源空间名
12651303
* @param fromFileKey 源文件的 key
@@ -1275,6 +1313,26 @@ public BatchOperations addCopyOp(String fromBucket, String fromFileKey, String t
12751313
return this;
12761314
}
12771315

1316+
/**
1317+
* 添加 copy 指令
1318+
*
1319+
* @param fromBucket 源空间名
1320+
* @param fromFileKey 源文件的 key
1321+
* @param toBucket 目标空间名
1322+
* @param toFileKey 目标文件的 key
1323+
* @param force 当目标文件已存在时,是否木盖目标文件
1324+
* false: 如果目标文件名已被占用,则返回错误码 614,且不做任何覆盖操作;
1325+
* true: 如果目标文件名已被占用,会强制覆盖目标文件
1326+
* @return BatchOperations
1327+
*/
1328+
public BatchOperations addCopyOp(String fromBucket, String fromFileKey, String toBucket, String toFileKey, boolean force) {
1329+
String from = encodedEntry(fromBucket, fromFileKey);
1330+
String to = encodedEntry(toBucket, toFileKey);
1331+
ops.add(String.format("copy/%s/%s/force/%s", from, to, force));
1332+
setExecBucket(fromBucket);
1333+
return this;
1334+
}
1335+
12781336
/**
12791337
* 添加重命名指令
12801338
*
@@ -1287,6 +1345,21 @@ public BatchOperations addRenameOp(String fromBucket, String fromFileKey, String
12871345
return addMoveOp(fromBucket, fromFileKey, fromBucket, toFileKey);
12881346
}
12891347

1348+
/**
1349+
* 添加重命名指令
1350+
*
1351+
* @param fromBucket 源空间名
1352+
* @param fromFileKey 源文件的 key
1353+
* @param toFileKey 目标文件的 key
1354+
* @param force 当目标文件已存在时,是否木盖目标文件
1355+
* false: 如果目标文件名已被占用,则返回错误码 614,且不做任何覆盖操作;
1356+
* true: 如果目标文件名已被占用,会强制覆盖目标文件
1357+
* @return BatchOperations
1358+
*/
1359+
public BatchOperations addRenameOp(String fromBucket, String fromFileKey, String toFileKey, boolean force) {
1360+
return addMoveOp(fromBucket, fromFileKey, fromBucket, toFileKey, force);
1361+
}
1362+
12901363
/**
12911364
* 添加move指令
12921365
*
@@ -1304,6 +1377,26 @@ public BatchOperations addMoveOp(String fromBucket, String fromKey, String toBuc
13041377
return this;
13051378
}
13061379

1380+
/**
1381+
* 添加move指令
1382+
*
1383+
* @param fromBucket 源空间名
1384+
* @param fromKey 源文件的 keys
1385+
* @param toBucket 目标空间名
1386+
* @param toKey 目标文件的 keys
1387+
* @param force 当目标文件已存在时,是否木盖目标文件
1388+
* false: 如果目标文件名已被占用,则返回错误码 614,且不做任何覆盖操作;
1389+
* true: 如果目标文件名已被占用,会强制覆盖目标文件
1390+
* @return BatchOperations
1391+
*/
1392+
public BatchOperations addMoveOp(String fromBucket, String fromKey, String toBucket, String toKey, boolean force) {
1393+
String from = encodedEntry(fromBucket, fromKey);
1394+
String to = encodedEntry(toBucket, toKey);
1395+
ops.add(String.format("move/%s/%s/force/%s", from, to, force));
1396+
setExecBucket(fromBucket);
1397+
return this;
1398+
}
1399+
13071400
/**
13081401
* 添加delete指令
13091402
*
@@ -1429,6 +1522,81 @@ public int size() {
14291522
}
14301523
}
14311524

1525+
public static final class Condition {
1526+
private final String hash;
1527+
private final String mime;
1528+
private final Long fSize;
1529+
private final Long putTime;
1530+
1531+
private Condition(String hash, String mime, Long fSize, Long putTime) {
1532+
this.hash = hash;
1533+
this.mime = mime;
1534+
this.fSize = fSize;
1535+
this.putTime = putTime;
1536+
}
1537+
1538+
String encodedString() {
1539+
StringBuilder builder = new StringBuilder();
1540+
if (hash != null && !hash.isEmpty()) {
1541+
builder.append("hash=" + hash + "&");
1542+
}
1543+
if (mime != null && !mime.isEmpty()) {
1544+
builder.append("mime=" + mime + "&");
1545+
}
1546+
if (fSize != null) {
1547+
builder.append("fsize=" + fSize + "&");
1548+
}
1549+
if (putTime != null) {
1550+
builder.append("putTime=" + putTime + "&");
1551+
}
1552+
1553+
String encoded = builder.toString();
1554+
if (encoded.isEmpty()) {
1555+
return null;
1556+
}
1557+
1558+
if (encoded.endsWith("&")) {
1559+
encoded = encoded.substring(0, encoded.length() - 1);
1560+
}
1561+
1562+
return UrlSafeBase64.encodeToString(encoded);
1563+
}
1564+
1565+
public static final class Builder {
1566+
private String hash;
1567+
private String mime;
1568+
private Long fileSize;
1569+
private Long putTime;
1570+
1571+
public Builder() {
1572+
}
1573+
1574+
public Builder setHash(String hash) {
1575+
this.hash = hash;
1576+
return this;
1577+
}
1578+
1579+
public Builder setMime(String mime) {
1580+
this.mime = mime;
1581+
return this;
1582+
}
1583+
1584+
public Builder setFileSize(Long fileSize) {
1585+
this.fileSize = fileSize;
1586+
return this;
1587+
}
1588+
1589+
public Builder setPutTime(Long putTime) {
1590+
this.putTime = putTime;
1591+
return this;
1592+
}
1593+
1594+
public Condition build() {
1595+
return new Condition(hash, mime, fileSize, putTime);
1596+
}
1597+
}
1598+
}
1599+
14321600
/**
14331601
* 创建文件列表迭代器
14341602
*/

src/main/java/com/qiniu/storage/Region.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ String getApiHost(RegionReqInfo regionReqInfo) throws QiniuException {
371371
}
372372

373373
String getUcHost(RegionReqInfo regionReqInfo) throws QiniuException {
374-
if (ucHosts == null || ucHosts.size() == 0) {
374+
if (ucHosts == null || ucHosts.isEmpty()) {
375375
return "";
376376
}
377377
return ucHosts.get(0);
@@ -470,6 +470,13 @@ public Builder apiHost(String apiHost) {
470470
return this;
471471
}
472472

473+
public Builder ucHost(String... ucHosts) {
474+
if (ucHosts.length > 0) {
475+
this.region.ucHosts = Arrays.asList(ucHosts);
476+
}
477+
return this;
478+
}
479+
473480
/**
474481
* 自动选择,其它参数设置无效
475482
*
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.qiniu.storage;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Tag;
5+
import org.junit.jupiter.api.Test;
6+
7+
public class BatchTest {
8+
9+
@Test
10+
@Tag("UnitTest")
11+
public void testBatchCondition() {
12+
13+
BucketManager.Condition condition = new BucketManager.Condition.Builder()
14+
.build();
15+
String encodedString = condition.encodedString();
16+
Assertions.assertNull(encodedString);
17+
18+
condition = new BucketManager.Condition.Builder()
19+
.setHash("hash")
20+
.build();
21+
encodedString = condition.encodedString();
22+
Assertions.assertEquals(encodedString, "aGFzaD1oYXNo");
23+
24+
condition = new BucketManager.Condition.Builder()
25+
.setHash("hash")
26+
.setPutTime(1993232L)
27+
.build();
28+
encodedString = condition.encodedString();
29+
Assertions.assertEquals(encodedString, "aGFzaD1oYXNoJnB1dFRpbWU9MTk5MzIzMg==");
30+
31+
condition = new BucketManager.Condition.Builder()
32+
.setHash("hash")
33+
.setMime("application/txt")
34+
.setPutTime(1993232L)
35+
.build();
36+
encodedString = condition.encodedString();
37+
Assertions.assertEquals(encodedString, "aGFzaD1oYXNoJm1pbWU9YXBwbGljYXRpb24vdHh0JnB1dFRpbWU9MTk5MzIzMg==");
38+
39+
condition = new BucketManager.Condition.Builder()
40+
.setHash("hash")
41+
.setMime("application/txt")
42+
.setFileSize(100L)
43+
.setPutTime(1993232L)
44+
.build();
45+
encodedString = condition.encodedString();
46+
Assertions.assertEquals(encodedString, "aGFzaD1oYXNoJm1pbWU9YXBwbGljYXRpb24vdHh0JmZzaXplPTEwMCZwdXRUaW1lPTE5OTMyMzI=");
47+
}
48+
}

src/test/java/test/com/qiniu/TestConfig.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public final class TestConfig {
2222
// test: ak, sk, auth
2323
public static final String testAccessKey = System.getenv("QINIU_ACCESS_KEY");
2424
public static final String testSecretKey = System.getenv("QINIU_SECRET_KEY");
25+
public static final String testBucket = System.getenv("BUCKET");
26+
public static final String testBucketDomain = System.getenv("BUCKET_DOMAIN");
27+
2528
// 内部测试环境 AK/SK
2629
public static final String innerAccessKey = System.getenv("testAK");
2730
public static final String innerSecretKey = System.getenv("testSK");
@@ -46,7 +49,10 @@ public final class TestConfig {
4649
public static final String testPipeline = "sdktest";
4750

4851
// z1
49-
public static final String testBucket_z1 = "sdk-z1";
52+
public static final String testBucket_z1 = "javasdk-z1";
53+
public static final String testKey_z1 = "do_not_delete/1.png";
54+
public static final String testDomain_z1 = "javasdk-z1.qiniupkg.com";
55+
public static final String testDomain_z1_timeStamp = "javasdk-timestamp.peterpy.cn";
5056

5157
// na0
5258
public static final String testBucket_na0 = "java-sdk-na0";
@@ -111,6 +117,17 @@ public static TestFile[] getTestFileArray(String fileSaveKey, String fileMimeTyp
111117
z0.regionId = "z0";
112118
z0.region = Region.createWithRegionId("z0");
113119

120+
TestFile z1 = new TestFile();
121+
z1.key = fileSaveKey;
122+
z1.mimeType = fileMimeType;
123+
z1.bucketName = testBucket_z1;
124+
z1.testDomain = testDomain_z1;
125+
z1.testUrl = "http://" + z1.testDomain + "/" + fileSaveKey;
126+
z1.testDomainTimeStamp = testDomain_z0_timeStamp;
127+
z1.testUrlTimeStamp = "http://" + testDomain_z0_timeStamp + "/" + fileSaveKey;
128+
z1.regionId = "z1";
129+
z1.region = Region.createWithRegionId("z1");
130+
114131
TestFile z0_auto = new TestFile();
115132
z0_auto.key = fileSaveKey;
116133
z0_auto.mimeType = fileMimeType;
@@ -122,7 +139,18 @@ public static TestFile[] getTestFileArray(String fileSaveKey, String fileMimeTyp
122139
z0_auto.regionId = "z0";
123140
z0_auto.region = Region.region0();
124141

125-
return new TestFile[]{z0};
142+
TestFile file = new TestFile();
143+
file.key = fileSaveKey;
144+
file.mimeType = fileMimeType;
145+
file.bucketName = (testBucket != null && !testBucket.isEmpty()) ? testBucket : testBucket_z0;
146+
file.testDomain = (testBucketDomain != null && !testBucketDomain.isEmpty()) ? testBucketDomain : testDomain_z0;
147+
file.testUrl = "http://" + file.testDomain + "/" + fileSaveKey;
148+
file.testDomainTimeStamp = testDomain_z0_timeStamp;
149+
file.testUrlTimeStamp = "http://" + testDomain_z0_timeStamp + "/" + fileSaveKey;
150+
file.regionId = "z0";
151+
file.region = testBucket_z1.equals(testBucket) ? Region.region1() : Region.region0();
152+
153+
return new TestFile[]{file};
126154
}
127155

128156
public static TestFile[] getAllRegionTestFileArray() {
@@ -221,7 +249,7 @@ public static TestFile[] getRetryTestFileArray() {
221249
regionGroup.addRegion(region00);
222250
regionGroup.addRegion(region01);
223251
na0.region = regionGroup;
224-
return new TestFile[] { na0 };
252+
return new TestFile[]{na0};
225253
}
226254

227255
private static Region toRegion(Zone zone) {

0 commit comments

Comments
 (0)