Skip to content
50 changes: 30 additions & 20 deletions src/main/java/com/qiniu/storage/FixBlockUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ public class FixBlockUploader {
private String host = null;

/**
* @param blockSize must be multiples of 4M.
* @param blockSize must be >= 4 * 1024 * 1024.
* @param configuration Nullable, if null, then create a new one.
* @param client Nullable, if null, then create a new one with configuration.
* @param recorder Nullable.
*/
public FixBlockUploader(int blockSize, Configuration configuration, Client client, Recorder recorder) {
assert blockSize > 0 && blockSize % (4 * 1024 * 1024) == 0 : "blockSize must be multiples of 4M ";
assert blockSize >= 4 * 1024 * 1024 : "blockSize must be >= 4M ";

if (configuration == null) {
configuration = new Configuration();
Expand Down Expand Up @@ -107,9 +107,9 @@ Response upload(BlockData blockData, Token token, String key, OptionsMeta params
/*
上传到七牛存储保存的文件名, 需要进行UrlSafeBase64编码。
注意:
当设置为空时表示空的文件名;
当设置为未进行 UrlSafeBase64 编码的字符 ~ 的时候,表示未设置文件名,
具体行为如分片上传v1: 使用文件的hash最为文件名, 如果设置了saveKey则使用saveKey的规则进行文件命名
当 key 为空 "" 时表示空的文件名,正常进行 url_safe_base64 编码;
当 key 为未进行 UrlSafeBase64 编码的字符 ~ 的时候表示未设置文件名,
具体行为如分片上传v1: 使用文件的 hash 作为文件名, 如果设置了saveKey则使用saveKey的规则进行文件命名
*/
String base64Key = key != null ? UrlSafeBase64.encodeToString(key) : "~";
String recordFileKey = (recorder == null) ? "NULL"
Expand All @@ -120,12 +120,15 @@ Response upload(BlockData blockData, Token token, String key, OptionsMeta params
host = configHelper.upHost(token.getUpToken());
}
UploadRecordHelper recordHelper = new UploadRecordHelper(recorder, recordFileKey, blockData.repeatable());
// 1. initParts
Record record = initUpload(blockData, recordHelper, bucket, base64Key, token);
boolean repeatable = recorder != null && blockData.repeatable();

Response res;
try {
// 2. uploadPart
upBlock(blockData, token, bucket, base64Key, repeatable, record, pool, maxRunningBlock);
// 3. completeParts
res = makeFile(bucket, base64Key, token, record.uploadId, record.etagIdxes,
blockData.getFileName(), params);
} catch (QiniuException e) {
Expand Down Expand Up @@ -154,14 +157,15 @@ record = null;
}

if (record == null || record.uploadId == null) {
String uploadId = init(bucket, base64Key, token.getUpToken());
InitRet ret = init(bucket, base64Key, token.getUpToken());

List<EtagIdx> etagIdxes = new ArrayList<>();
record = initRecord(uploadId, etagIdxes);
record = initRecord(ret, etagIdxes);
}
return record;
}

String init(String bucket, String base64Key, String upToken) throws QiniuException {
InitRet init(String bucket, String base64Key, String upToken) throws QiniuException {
String url = host + "/buckets/" + bucket + "/objects/" + base64Key + "/uploads";
byte[] data = new byte[0];
StringMap headers = new StringMap().put("Authorization", "UpToken " + upToken);
Expand Down Expand Up @@ -205,9 +209,9 @@ String init(String bucket, String base64Key, String upToken) throws QiniuExcepti
}

try {
String uploadId = res.jsonToMap().get("uploadId").toString();
if (uploadId.length() > 10) {
return uploadId;
InitRet ret = res.jsonToObject(InitRet.class);
if (ret != null && ret.uploadId != null && ret.uploadId.length() > 10 && ret.expireAt > 1000) {
return ret;
}
} catch (Exception e) {
// ignore, see next line
Expand Down Expand Up @@ -432,7 +436,7 @@ Response makeFile(String bucket, String base64Key, Token token, String uploadId,
String fileName, OptionsMeta params) throws QiniuException {
String url = host + "/buckets/" + bucket + "/objects/" + base64Key + "/uploads/" + uploadId;
final StringMap headers = new StringMap().put("Authorization", "UpToken " + token.getUpToken());
sortAsc(etags);
sortByPartNumberAsc(etags);
byte[] data = new MakefileBody(etags, fileName, params)
.json().getBytes(Charset.forName("UTF-8"));

Expand Down Expand Up @@ -493,7 +497,7 @@ private String parseBucket(String upToken) throws QiniuException {
}
}

static void sortAsc(List<EtagIdx> etags) {
static void sortByPartNumberAsc(List<EtagIdx> etags) {
Collections.sort(etags, new Comparator<EtagIdx>() {
@Override
public int compare(EtagIdx o1, EtagIdx o2) {
Expand Down Expand Up @@ -567,17 +571,19 @@ public String toString() {


class Record {
long createdTime;
// second
long expireAt;
String uploadId;
long size;
List<EtagIdx> etagIdxes;
}


Record initRecord(String uploadId, List<EtagIdx> etagIdxes) {
Record initRecord(InitRet ret, List<EtagIdx> etagIdxes) {
Record record = new Record();
record.createdTime = System.currentTimeMillis();
record.uploadId = uploadId;
record.uploadId = ret.uploadId;
//// 服务端 7 天内有效,设置 5 天 ////
record.expireAt = ret.expireAt - 3600 * 24 * 2;
record.size = 0;
record.etagIdxes = etagIdxes != null ? etagIdxes : new ArrayList<EtagIdx>();

Expand Down Expand Up @@ -620,15 +626,14 @@ public void delRecord() {

public void syncRecord(Record record) {
if (needRecord && recorder != null && record.etagIdxes.size() > 0) {
sortAsc(record.etagIdxes);
sortByPartNumberAsc(record.etagIdxes);
recorder.set(recordFileKey, new Gson().toJson(record).getBytes(Charset.forName("UTF-8")));
}
}

public boolean isActiveRecord(Record record, BlockData blockData) {
//// 服务端 7 天内有效,设置 5 天 ////
boolean isOk = record != null
&& record.createdTime > System.currentTimeMillis() - 1000 * 3600 * 24 * 5
&& record.expireAt < (System.currentTimeMillis() / 1000)
&& !StringUtils.isNullOrEmpty(record.uploadId)
&& record.etagIdxes != null && record.etagIdxes.size() > 0
&& record.size > 0 && record.size <= blockData.size();
Expand All @@ -652,6 +657,11 @@ public boolean isActiveRecord(Record record, BlockData blockData) {

///////////////////////////////////////

class InitRet {
String uploadId;
long expireAt;
}


abstract static class BlockData {
protected final int blockDataSize;
Expand Down
13 changes: 12 additions & 1 deletion src/test/java/test/com/qiniu/storage/FixBlockUploaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class FixBlockUploaderTest {
int blockSize = 1024 * 1024 * 8;
Expand All @@ -45,6 +46,17 @@ private void init2(boolean useHttpsDomains) {
bm = new BucketManager(TestConfig.testAuth, config);
}

@Test
public void testInit() {
Configuration config = new Configuration();
Client client = new Client(config);
try {
new FixBlockUploader(1024 * 1024 * 3, config, client, null);
fail("block size must be >= 1024 * 1024 * 4");
} catch (AssertionError e) {
assertTrue(e.getMessage().indexOf("blockSize must be >= 4M") > -1);
}
}

@Test
public void testEmpty() throws IOException {
Expand Down Expand Up @@ -278,5 +290,4 @@ class MyRet {
public String mimeType;
public String biu2biu;
}

}