Skip to content

Commit 143caa8

Browse files
authored
Merge pull request #241 from tencentyun/dev/error_code_retry
rename fault tolerant
2 parents 1340d08 + e1cc335 commit 143caa8

File tree

6 files changed

+82
-2
lines changed

6 files changed

+82
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [5.6.246]
9+
- rename fault tolerant
10+
811
## [5.6.244.4]
912
- 3xx exception retry
1013

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.qcloud</groupId>
66
<artifactId>cos_api</artifactId>
7-
<version>5.6.244.4</version>
7+
<version>5.6.246</version>
88
<packaging>jar</packaging>
99
<name>cos-java-sdk</name>
1010
<description>java sdk for qcloud cos</description>

src/main/java/com/qcloud/cos/COSClient.java

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,11 +814,72 @@ public void rename(RenameRequest renameRequest)
814814
"region is null, region in clientConfig must be specified when rename");
815815
rejectEmpty(renameRequest.getSrcObject(), "The length of the src key must be greater than 0");
816816
rejectEmpty(renameRequest.getDstObject(), "The length of the dst key must be greater than 0");
817+
818+
String srcInodeId = "";
819+
if (clientConfig.isRenameFaultTolerant()) {
820+
srcInodeId = getObjectInodeId(renameRequest.getBucketName(), renameRequest.getSrcObject(), renameRequest.getFixedEndpointAddr(),
821+
renameRequest.getCustomRequestHeaders());
822+
}
823+
817824
CosHttpRequest<RenameRequest> request = createRequest(renameRequest.getBucketName(),
818825
renameRequest.getDstObject(), renameRequest, HttpMethodName.PUT);
819826
request.addParameter("rename", null);
820827
request.addHeader("x-cos-rename-source", UrlEncoderUtils.encodeEscapeDelimiter(renameRequest.getSrcObject()));
821-
invoke(request, voidCosResponseHandler);
828+
try {
829+
invoke(request, voidCosResponseHandler);
830+
} catch (CosServiceException cse) {
831+
if (clientConfig.isRenameFaultTolerant() && cse.getStatusCode() == 404 && !srcInodeId.isEmpty()) {
832+
if (!checkResultForRenameObject(srcInodeId, renameRequest)) {
833+
throw cse;
834+
}
835+
} else {
836+
throw cse;
837+
}
838+
}
839+
}
840+
841+
private boolean checkResultForRenameObject(String srcInodeId, RenameRequest renameRequest) {
842+
/**
843+
* try to head src object and dst object, and check their inode ids when catch exception
844+
* rename request is successful only if src object does not exist and the inode ids of the source object and the target object are the same
845+
* */
846+
try {
847+
getObjectInodeId(renameRequest.getBucketName(), renameRequest.getSrcObject(), renameRequest.getFixedEndpointAddr(), renameRequest.getCustomRequestHeaders());
848+
} catch (CosServiceException cse) {
849+
if (cse.getStatusCode() != 404) {
850+
log.info("catch CosServiceException and status code is not 404 when getting the inode id of the source object, exp: ", cse);
851+
return false;
852+
}
853+
} catch (CosClientException cce) {
854+
log.info("catch CosClientException when getting the inode id of the source object, exp: ", cce);
855+
return false;
856+
}
857+
858+
String dstInodeId;
859+
try {
860+
dstInodeId = getObjectInodeId(renameRequest.getBucketName(), renameRequest.getDstObject(), renameRequest.getFixedEndpointAddr(), renameRequest.getCustomRequestHeaders());
861+
} catch (Exception e) {
862+
log.info("catch exception when getting the inode id of the target object, exp: ", e);
863+
return false;
864+
}
865+
return Objects.equals(dstInodeId, srcInodeId);
866+
}
867+
868+
private String getObjectInodeId(String bucketName, String key, String fixedEndpointAddr, Map<String, String> customHeaders)
869+
throws CosServiceException, CosClientException {
870+
GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest(bucketName, key);
871+
if (fixedEndpointAddr != null && !fixedEndpointAddr.isEmpty()) {
872+
getObjectMetadataRequest.setFixedEndpointAddr(fixedEndpointAddr);
873+
}
874+
875+
if (customHeaders != null) {
876+
for (Map.Entry<String, String> e : customHeaders.entrySet()) {
877+
getObjectMetadataRequest.putCustomRequestHeader(e.getKey(), e.getValue());
878+
}
879+
}
880+
881+
ObjectMetadata objectMetadata = getObjectMetadata(getObjectMetadataRequest);
882+
return objectMetadata.getInodeId() == null ? "" : objectMetadata.getInodeId();
822883
}
823884

824885
protected <UploadObjectRequest extends PutObjectRequest>

src/main/java/com/qcloud/cos/ClientConfig.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ public class ClientConfig {
145145

146146
private boolean throw304Directly = false;
147147

148+
private boolean renameFaultTolerant = false;
149+
148150
// 不传入region 用于后续调用List Buckets(获取所有的bucket信息)
149151
public ClientConfig() {
150152
super();
@@ -537,4 +539,12 @@ public boolean isThrow304Directly() {
537539
public void setThrow304Directly(boolean throw304Directly) {
538540
this.throw304Directly = throw304Directly;
539541
}
542+
543+
public boolean isRenameFaultTolerant() {
544+
return renameFaultTolerant;
545+
}
546+
547+
public void setRenameFaultTolerant(boolean renameFaultTolerant) {
548+
this.renameFaultTolerant = renameFaultTolerant;
549+
}
540550
}

src/main/java/com/qcloud/cos/Headers.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,6 @@ public interface Headers {
334334
public static final String ENCRYPTION_PART_SIZE = "client-side-encryption-part-size";
335335

336336
public static final String SYMLINK_TARGET = "x-cos-symlink-target";
337+
338+
public static final String INODE_ID = "x-cos-inode-id";
337339
}

src/main/java/com/qcloud/cos/model/ObjectMetadata.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,4 +842,8 @@ public boolean isNeedPreflight() {
842842
}
843843
return false;
844844
}
845+
846+
public String getInodeId() {
847+
return (String) metadata.get(Headers.INODE_ID);
848+
}
845849
}

0 commit comments

Comments
 (0)