From d402231ebca80a0341ca8e30bf743e5fd4bc8b89 Mon Sep 17 00:00:00 2001 From: noaccident Date: Thu, 30 Oct 2025 17:38:52 +0800 Subject: [PATCH] updata 3.25.10 --- README-Android.md | 6 + README-Java.md | 6 + README_CN.MD | 6 + app/pom.xml | 2 +- .../services/AbstractBucketAdvanceClient.java | 30 ++ .../obs/services/AbstractBucketClient.java | 182 +++++++++ .../obs/services/AbstractObjectClient.java | 1 + .../java/com/obs/services/IObsClient.java | 70 +++- .../obs/services/exception/ObsException.java | 10 + .../com/obs/services/internal/Constants.java | 8 +- .../com/obs/services/internal/IConvertor.java | 4 + .../obs/services/internal/ObsConstraint.java | 32 +- .../obs/services/internal/ObsConvertor.java | 14 + .../services/internal/ServiceException.java | 10 + .../services/internal/V2BucketConvertor.java | 3 + .../obs/services/internal/V2Convertor.java | 31 ++ .../handler/XmlResponsesSaxParser.java | 371 ++++++++++++++++++ .../service/ObsBucketAdvanceService.java | 103 ++++- .../service/ObsBucketBaseService.java | 164 +++++++- .../internal/service/RequestConvertor.java | 21 + .../services/internal/utils/Mimetypes.java | 12 +- .../services/internal/utils/ServiceUtils.java | 47 +++ .../xml/QosConfigurationXMLBuilder.java | 101 +++++ .../services/model/BaseSnapshotRequest.java | 23 ++ .../services/model/CreateSnapshotRequest.java | 20 + .../model/CreateSnapshotResponse.java | 16 + .../model/DeleteBucketLifecycleRequest.java | 46 +++ .../services/model/DeleteSnapshotRequest.java | 14 + .../model/GetBucketLifecycleRequest.java | 60 +++ .../model/GetSnapshotListRequest.java | 139 +++++++ .../model/GetSnapshotListResponse.java | 149 +++++++ .../model/GetSnapshottableDirListRequest.java | 106 +++++ .../model/GetSnapshottableDirListResult.java | 52 +++ .../model/LifecycleConfiguration.java | 4 +- .../services/model/ListVersionsResult.java | 23 +- .../model/Qos/BpsLimitConfiguration.java | 53 +++ .../model/Qos/DeleteBucketQosRequest.java | 16 + .../model/Qos/GetBucketQoSRequest.java | 14 + .../model/Qos/GetBucketQoSResult.java | 65 +++ .../obs/services/model/Qos/NetworkType.java | 34 ++ .../services/model/Qos/QosConfiguration.java | 42 ++ .../com/obs/services/model/Qos/QosRule.java | 56 +++ .../model/Qos/QpsLimitConfiguration.java | 63 +++ .../model/Qos/SetBucketQosRequest.java | 23 ++ .../services/model/RenameSnapshotRequest.java | 96 +++++ .../model/RenameSnapshotResponse.java | 16 + .../model/SetBucketLifecycleRequest.java | 15 + .../model/SetDisallowSnapshotRequest.java | 41 ++ .../model/SetSnapshotAllowRequest.java | 41 ++ .../java/com/obs/services/model/Snapshot.java | 103 +++++ .../obs/services/model/SnapshottableDir.java | 43 ++ .../obs/services/model/SpecialParamEnum.java | 8 +- .../model/symlink/GetSymlinkRequest.java | 4 + .../model/symlink/PutSymlinkRequest.java | 5 + pom-android.xml | 2 +- pom-dependencies.xml | 2 +- pom-java-optimization.xml | 2 +- pom-java.xml | 2 +- pom.xml | 2 +- 59 files changed, 2601 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/com/obs/services/internal/xml/QosConfigurationXMLBuilder.java create mode 100644 app/src/main/java/com/obs/services/model/BaseSnapshotRequest.java create mode 100644 app/src/main/java/com/obs/services/model/CreateSnapshotRequest.java create mode 100644 app/src/main/java/com/obs/services/model/CreateSnapshotResponse.java create mode 100644 app/src/main/java/com/obs/services/model/DeleteBucketLifecycleRequest.java create mode 100644 app/src/main/java/com/obs/services/model/DeleteSnapshotRequest.java create mode 100644 app/src/main/java/com/obs/services/model/GetBucketLifecycleRequest.java create mode 100644 app/src/main/java/com/obs/services/model/GetSnapshotListRequest.java create mode 100644 app/src/main/java/com/obs/services/model/GetSnapshotListResponse.java create mode 100644 app/src/main/java/com/obs/services/model/GetSnapshottableDirListRequest.java create mode 100644 app/src/main/java/com/obs/services/model/GetSnapshottableDirListResult.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/BpsLimitConfiguration.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/DeleteBucketQosRequest.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/GetBucketQoSRequest.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/GetBucketQoSResult.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/NetworkType.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/QosConfiguration.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/QosRule.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/QpsLimitConfiguration.java create mode 100644 app/src/main/java/com/obs/services/model/Qos/SetBucketQosRequest.java create mode 100644 app/src/main/java/com/obs/services/model/RenameSnapshotRequest.java create mode 100644 app/src/main/java/com/obs/services/model/RenameSnapshotResponse.java create mode 100644 app/src/main/java/com/obs/services/model/SetDisallowSnapshotRequest.java create mode 100644 app/src/main/java/com/obs/services/model/SetSnapshotAllowRequest.java create mode 100644 app/src/main/java/com/obs/services/model/Snapshot.java create mode 100644 app/src/main/java/com/obs/services/model/SnapshottableDir.java diff --git a/README-Android.md b/README-Android.md index b3b7621..0906df3 100644 --- a/README-Android.md +++ b/README-Android.md @@ -1,3 +1,9 @@ +Version 3.25.10 +New features: +1. Support for Posix snapshot features +2. Support for bucket QoS features +3. Support Lifecycle 2.0 +----------------------------------------------------------------------------------- Version 3.25.7 New features: 1. Added symlink feature diff --git a/README-Java.md b/README-Java.md index fdb5975..6178636 100644 --- a/README-Java.md +++ b/README-Java.md @@ -1,3 +1,9 @@ +Version 3.25.10 +New features: +1. Support for Posix snapshot features +2. Support for bucket QoS features +3. Support Lifecycle 2.0 +----------------------------------------------------------------------------------- Version 3.25.7 New features: 1. Added symlink feature diff --git a/README_CN.MD b/README_CN.MD index 7de1617..38c2885 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -1,3 +1,9 @@ +Version 3.25.10 +New features: +1. 支持并行文件系统快照特性 +2. 支持桶qos特性 +3. 支持生命周期2.0 +----------------------------------------------------------------------------------- Version 3.25.7 New features: 1. 支持软链接特性 diff --git a/app/pom.xml b/app/pom.xml index 4b3721a..c755e67 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java-android - 3.25.7 + 3.25.10 OBS SDK for Java/Android The OBS SDK for Android used for accessing Object Storage Service diff --git a/app/src/main/java/com/obs/services/AbstractBucketAdvanceClient.java b/app/src/main/java/com/obs/services/AbstractBucketAdvanceClient.java index 2e17bc2..2ee8fb2 100644 --- a/app/src/main/java/com/obs/services/AbstractBucketAdvanceClient.java +++ b/app/src/main/java/com/obs/services/AbstractBucketAdvanceClient.java @@ -18,6 +18,8 @@ import com.obs.services.exception.ObsException; import com.obs.services.internal.ServiceException; import com.obs.services.internal.utils.ServiceUtils; +import com.obs.services.model.DeleteBucketLifecycleRequest; +import com.obs.services.model.GetBucketLifecycleRequest; import com.obs.services.model.bpa.DeleteBucketPublicAccessBlockRequest; import com.obs.services.model.bpa.GetBucketPolicyPublicStatusRequest; import com.obs.services.model.bpa.GetBucketPolicyPublicStatusResult; @@ -85,6 +87,20 @@ public LifecycleConfiguration action() throws ServiceException { }); } + @Override + public LifecycleConfiguration getBucketLifecycle(final GetBucketLifecycleRequest request) throws ObsException { + ServiceUtils.assertParameterNotNull(request, "GetBucketLifecycleRequest is null"); + ServiceUtils.assertParameterNotNull2(request.getBucketName(), "bucketName is null"); + return this.doActionWithResult("getBucketLifecycleConfiguration", request.getBucketName(), + new ActionCallbackWithResult() { + + @Override + public LifecycleConfiguration action() throws ServiceException { + return AbstractBucketAdvanceClient.this.getBucketLifecycleConfigurationImpl(request); + } + }); + } + /* * (non-Javadoc) * @@ -147,6 +163,20 @@ public HeaderResponse action() throws ServiceException { } + @Override + public HeaderResponse deleteBucketLifecycle(final DeleteBucketLifecycleRequest request) throws ObsException { + ServiceUtils.assertParameterNotNull(request, "DeleteBucketLifecycleRequest is null"); + ServiceUtils.assertParameterNotNull2(request.getBucketName(), "bucketName is null"); + return this.doActionWithResult("deleteBucketLifecycleConfiguration", request.getBucketName(), + new ActionCallbackWithResult() { + @Override + public HeaderResponse action() throws ServiceException { + return AbstractBucketAdvanceClient.this.deleteBucketLifecycleConfigurationImpl(request); + } + }); + + } + /* * (non-Javadoc) * diff --git a/app/src/main/java/com/obs/services/AbstractBucketClient.java b/app/src/main/java/com/obs/services/AbstractBucketClient.java index 814ccc0..080029e 100644 --- a/app/src/main/java/com/obs/services/AbstractBucketClient.java +++ b/app/src/main/java/com/obs/services/AbstractBucketClient.java @@ -16,8 +16,11 @@ package com.obs.services; import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; import com.obs.services.exception.ObsException; +import com.obs.services.internal.ObsConstraint; import com.obs.services.internal.ServiceException; import com.obs.services.internal.utils.ServiceUtils; import com.obs.services.model.AccessControlList; @@ -34,16 +37,31 @@ import com.obs.services.model.BucketStoragePolicyConfiguration; import com.obs.services.model.BucketVersioningConfiguration; import com.obs.services.model.CreateBucketRequest; +import com.obs.services.model.CreateSnapshotRequest; +import com.obs.services.model.CreateSnapshotResponse; import com.obs.services.model.CreateVirtualBucketRequest; import com.obs.services.model.CreateVirtualBucketResult; import com.obs.services.model.CustomDomainCertificateConfig; import com.obs.services.model.DeleteBucketCustomDomainRequest; +import com.obs.services.model.DeleteBucketLifecycleRequest; +import com.obs.services.model.DeleteSnapshotRequest; import com.obs.services.model.GetBucketCustomDomainRequest; +import com.obs.services.model.GetSnapshottableDirListRequest; +import com.obs.services.model.GetSnapshottableDirListResult; +import com.obs.services.model.GetSnapshotListRequest; +import com.obs.services.model.GetSnapshotListResponse; import com.obs.services.model.HeaderResponse; import com.obs.services.model.ListBucketAliasResult; import com.obs.services.model.ListBucketsRequest; import com.obs.services.model.ListBucketsResult; import com.obs.services.model.ObsBucket; +import com.obs.services.model.Qos.DeleteBucketQosRequest; +import com.obs.services.model.Qos.GetBucketQoSRequest; +import com.obs.services.model.Qos.GetBucketQoSResult; +import com.obs.services.model.Qos.SetBucketQosRequest; +import com.obs.services.model.Qos.QosRule; +import com.obs.services.model.RenameSnapshotRequest; +import com.obs.services.model.RenameSnapshotResponse; import com.obs.services.model.RequestPaymentConfiguration; import com.obs.services.model.RequestPaymentEnum; import com.obs.services.model.SetBucketAclRequest; @@ -54,6 +72,8 @@ import com.obs.services.model.SetBucketRequestPaymentRequest; import com.obs.services.model.SetBucketStoragePolicyRequest; import com.obs.services.model.SetBucketVersioningRequest; +import com.obs.services.model.SetDisallowSnapshotRequest; +import com.obs.services.model.SetSnapshotAllowRequest; import com.obs.services.model.inventory.SetInventoryConfigurationRequest; import com.obs.services.model.inventory.GetInventoryConfigurationRequest; import com.obs.services.model.inventory.DeleteInventoryConfigurationRequest; @@ -61,8 +81,34 @@ import com.obs.services.model.inventory.GetInventoryConfigurationResult; import com.obs.services.model.inventory.ListInventoryConfigurationResult; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_FULL_PATH; + public abstract class AbstractBucketClient extends AbstractDeprecatedBucketClient { + + private T executeAction(String actionName, + R request, + Function nameExtractor, + Runnable additionalValidation, + Supplier implementation) throws ObsException { + ServiceUtils.assertParameterNotNull(request, "request is null"); + + String bucketName = nameExtractor.apply(request); + ServiceUtils.assertParameterNotNull2(bucketName, "bucketName is null"); + + if (additionalValidation != null) { + additionalValidation.run(); + } + return this.doActionWithResult(actionName, bucketName, + new ActionCallbackWithResult() { + @Override + public T action() throws ServiceException { + return implementation.get(); + } + }); + } + /* * (non-Javadoc) * @@ -987,4 +1033,140 @@ public HeaderResponse action() throws ServiceException { }); } + + @Override + public HeaderResponse setBucketQos(SetBucketQosRequest request) throws ObsException { + ServiceUtils.assertParameterNotNull(request,"setBucketQosRequest is null"); + ServiceUtils.assertParameterNotNull(request.getBucketName(),"bucketName is null"); + ServiceUtils.assertParameterNotNull(request.getQosConfig(),"QosConfig is null"); + ServiceUtils.assertParameterNotNull(request.getQosConfig().getRules(),"rules is null"); + + List rules = request.getQosConfig().getRules(); + + if (rules.isEmpty()) { + throw new IllegalArgumentException("rules is empty"); + } + + for (QosRule rule : rules) { + ServiceUtils.assertParameterNotNull(rule.getNetworkType(), "networkType is null"); + ServiceUtils.assertParameterNotNull(rule.getQpsLimit(), "qpsLimit is null"); + ServiceUtils.assertParameterNotNull(rule.getBpsLimit(), "bpsLimit is null"); + } + return this.doActionWithResult("setBucketQoS", request.getBucketName(), + new ActionCallbackWithResult() { + @Override + public HeaderResponse action() throws ServiceException { + return AbstractBucketClient.this.setBucketQosImpl(request); + } + }); + } + + @Override + public GetBucketQoSResult getBucketQoS(GetBucketQoSRequest request) { + ServiceUtils.assertParameterNotNull(request.getBucketName(), "bucketName is null"); + return this.doActionWithResult("getBucketQos", request.getBucketName(), new ActionCallbackWithResult() { + @Override + public GetBucketQoSResult action() throws ServiceException { + return AbstractBucketClient.this.getBucketQosImpl(request); + } + }); + } + @Override + public HeaderResponse deleteBucketQoS(DeleteBucketQosRequest request) throws ObsException{ + ServiceUtils.assertParameterNotNull(request.getBucketName(),"bucketName is null"); + return this.doActionWithResult("deleteBucketQos", request.getBucketName(), new ActionCallbackWithResult() { + @Override + public HeaderResponse action() throws ServiceException { + return AbstractBucketClient.this.deleteBucketQosImpl(request); + } + }); + } + + public HeaderResponse deleteSnapshot(DeleteSnapshotRequest request) throws ObsException { + return executeAction("deleteSnapshot", request, DeleteSnapshotRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNull2(request.getObjectKey(), "objectKey is null"); + ServiceUtils.assertParameterNotNull2(request.getSnapshotName(), "snapshotName is null"); + }, + () -> AbstractBucketClient.this.deleteSnapshotImpl(request) + ); + } + + @Override + public HeaderResponse setSnapshotAllow(SetSnapshotAllowRequest request) throws ObsException { + return executeAction("setSnapshotAllow", request, SetSnapshotAllowRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNull2(request.getObjectKey(), "objectKey is null"); + }, + () -> AbstractBucketClient.this.setSnapshotAllowImpl(request) + ); + } + + @Override + public HeaderResponse setDisallowSnapshot(SetDisallowSnapshotRequest request) throws ObsException { + return executeAction("setDisallowSnapshot", request, SetDisallowSnapshotRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNull2(request.getObjectKey(), "objectKey is null"); + }, + () -> AbstractBucketClient.this.setDisallowSnapshotImpl(request) + ); + } + + @Override + public GetSnapshottableDirListResult getSnapshottableDirList(GetSnapshottableDirListRequest request) throws ObsException { + return executeAction("getSnapshottableDirList", request, GetSnapshottableDirListRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNegative(request.getMaxKeys(), "maxKeys is negative"); + }, + () -> AbstractBucketClient.this.getSnapshottableDirListImpl(request) + ); + } + + /** + * Get snapshot list for a bucket or object + */ + @Override + public GetSnapshotListResponse getSnapshotList(GetSnapshotListRequest request) throws ObsException { + return executeAction("getSnapshotList", request, GetSnapshotListRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNegative(request.getMaxKeys(), "maxKeys is negative"); + }, + () -> AbstractBucketClient.this.getSnapshotListImpl(request) + ); + } + + /** + * Create snapshot for an object + */ + @Override + public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest request) throws ObsException { + return executeAction("createSnapshot", request, CreateSnapshotRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNull2(request.getObjectKey(), "objectKey is null"); + ServiceUtils.assertParameterNotNull2(request.getSnapshotName(), "snapshotName is null"); + ServiceUtils.checkParameterLength(SNAPSHOT, request.getSnapshotName(), + 1, ObsConstraint.SNAPSHOT_NAME_MAX_LENGTH); + ServiceUtils.checkParameterLength(SNAPSHOT_FULL_PATH, request.getObjectKey(), + 1, ObsConstraint.SNAPSHOT_FULL_PATH_MAX_LENGTH); + }, + () -> AbstractBucketClient.this.createSnapshotImpl(request) + ); + } + + /** + * Rename snapshot for an object + */ + @Override + public RenameSnapshotResponse renameSnapshot(RenameSnapshotRequest request) throws ObsException { + return executeAction("renameSnapshot", request, RenameSnapshotRequest::getBucketName, + () -> { + ServiceUtils.assertParameterNotNull2(request.getObjectKey(), "objectKey is null"); + ServiceUtils.assertParameterNotNull2(request.getOldSnapshotName(), "oldSnapshotName is null"); + ServiceUtils.assertParameterNotNull2(request.getNewSnapshotName(), "newSnapshotName is null"); + }, + () -> AbstractBucketClient.this.renameSnapshotImpl(request) + ); + } + + public abstract HeaderResponse deleteBucketLifecycle(DeleteBucketLifecycleRequest request) throws ObsException; } diff --git a/app/src/main/java/com/obs/services/AbstractObjectClient.java b/app/src/main/java/com/obs/services/AbstractObjectClient.java index 6798b3b..9751eba 100644 --- a/app/src/main/java/com/obs/services/AbstractObjectClient.java +++ b/app/src/main/java/com/obs/services/AbstractObjectClient.java @@ -846,6 +846,7 @@ public HeaderResponse putSymlink(PutSymlinkRequest request) throws ObsException ServiceUtils.assertParameterNotNull(request, "PutSymlinkRequest is null"); ServiceUtils.assertParameterNotNull(request.getBucketName(), "bucketName is null"); ServiceUtils.assertParameterNotNull(request.getObjectKey(), "objectKey is null"); + ServiceUtils.assertParameterNotNull(request.getSymlinkTarget(), "symlinkTarget is null"); return this.doActionWithResult("putSymlink", request.getBucketName(), new ActionCallbackWithResult() { diff --git a/app/src/main/java/com/obs/services/IObsClient.java b/app/src/main/java/com/obs/services/IObsClient.java index 0c72721..d3e7e57 100644 --- a/app/src/main/java/com/obs/services/IObsClient.java +++ b/app/src/main/java/com/obs/services/IObsClient.java @@ -24,6 +24,22 @@ import com.obs.services.model.AccessControlList; import com.obs.services.model.AppendObjectRequest; import com.obs.services.model.AppendObjectResult; +import com.obs.services.model.DeleteBucketLifecycleRequest; +import com.obs.services.model.GetBucketLifecycleRequest; +import com.obs.services.model.Qos.DeleteBucketQosRequest; +import com.obs.services.model.Qos.GetBucketQoSRequest; +import com.obs.services.model.Qos.GetBucketQoSResult; +import com.obs.services.model.Qos.SetBucketQosRequest; +import com.obs.services.model.CreateSnapshotRequest; +import com.obs.services.model.CreateSnapshotResponse; +import com.obs.services.model.DeleteSnapshotRequest; +import com.obs.services.model.GetSnapshottableDirListRequest; +import com.obs.services.model.GetSnapshottableDirListResult; +import com.obs.services.model.GetSnapshotListRequest; +import com.obs.services.model.RenameSnapshotRequest; +import com.obs.services.model.RenameSnapshotResponse; +import com.obs.services.model.SetDisallowSnapshotRequest; +import com.obs.services.model.SetSnapshotAllowRequest; import com.obs.services.model.bpa.DeleteBucketPublicAccessBlockRequest; import com.obs.services.model.bpa.GetBucketPolicyPublicStatusRequest; import com.obs.services.model.bpa.GetBucketPolicyPublicStatusResult; @@ -1058,6 +1074,18 @@ HeaderResponse setBucketVersioning(String bucketName, BucketVersioningConfigurat */ LifecycleConfiguration getBucketLifecycle(BaseBucketRequest request) throws ObsException; + /** + * Obtain the bucket lifecycle rules. + * + * @param request + * Request parameters + * @return Bucket lifecycle rules + * @throws ObsException + * OBS SDK self-defined exception, thrown when the interface fails to be called or access to OBS fails + * @since 3.25.10 + */ + LifecycleConfiguration getBucketLifecycle(GetBucketLifecycleRequest request) throws ObsException; + /** * Set the bucket lifecycle rules. * @@ -1108,6 +1136,19 @@ HeaderResponse setBucketVersioning(String bucketName, BucketVersioningConfigurat */ HeaderResponse deleteBucketLifecycle(BaseBucketRequest request) throws ObsException; + + /** + * Delete the bucket lifecycle rules from a bucket. + * + * @param request + * Request parameters + * @return Common response headers + * @throws ObsException + * OBS SDK self-defined exception, thrown when the interface fails to be called or access to OBS fails + * @since 3.25.10 + */ + HeaderResponse deleteBucketLifecycle(DeleteBucketLifecycleRequest request) throws ObsException; + /** * Obtain bucket policies. * @@ -2342,12 +2383,33 @@ UploadPartResult uploadPart(String bucketName, String objectKey, String uploadId GetSymlinkResult getSymlink(GetSymlinkRequest request) throws ObsException; + HeaderResponse setBucketQos(SetBucketQosRequest request) throws ObsException; + + GetBucketQoSResult getBucketQoS(GetBucketQoSRequest request); + + HeaderResponse deleteBucketQoS(DeleteBucketQosRequest request) throws ObsException; + + HeaderResponse deleteSnapshot(DeleteSnapshotRequest request) throws ObsException; + + HeaderResponse setSnapshotAllow(SetSnapshotAllowRequest request) throws ObsException; + + HeaderResponse setDisallowSnapshot(SetDisallowSnapshotRequest request) throws ObsException; + /** - * Close ObsClient and release connection resources. - * - * @throws IOException - * ObsClient close exception + * Get snapshot list for a bucket or object + */ + HeaderResponse getSnapshotList(GetSnapshotListRequest request) throws ObsException; + + GetSnapshottableDirListResult getSnapshottableDirList(GetSnapshottableDirListRequest request) throws ObsException; + + CreateSnapshotResponse createSnapshot(CreateSnapshotRequest request) throws ObsException; + + + /** + * Rename snapshot for an object */ + RenameSnapshotResponse renameSnapshot(RenameSnapshotRequest request) throws ObsException; + void close() throws IOException; } diff --git a/app/src/main/java/com/obs/services/exception/ObsException.java b/app/src/main/java/com/obs/services/exception/ObsException.java index b33cefd..99840b5 100644 --- a/app/src/main/java/com/obs/services/exception/ObsException.java +++ b/app/src/main/java/com/obs/services/exception/ObsException.java @@ -47,6 +47,7 @@ public class ObsException extends RuntimeException { private boolean calledToSting = false; + private String encodedAuthorizationMessage = null; public ObsException(String message) { this(message, null, null); } @@ -132,6 +133,7 @@ private void parseXmlMessage(String xmlMsg) { this.errorMessage = findXmlElementText(xmlMsg, "Message"); this.errorRequestId = findXmlElementText(xmlMsg, "RequestId"); this.errorHostId = findXmlElementText(xmlMsg, "HostId"); + this.encodedAuthorizationMessage = findXmlElementText(xmlMsg, "EncodedAuthorizationMessage"); } public String getXmlMessage() { @@ -247,4 +249,12 @@ public void setErrorIndicator(String errorIndicator) { this.errorIndicator = errorIndicator; } + public String getEncodedAuthorizationMessage(){ + return this.encodedAuthorizationMessage; + } + + public void setEncodedAuthorizationMessage(String encodedAuthorizationMessage){ + this.encodedAuthorizationMessage = encodedAuthorizationMessage; + } + } diff --git a/app/src/main/java/com/obs/services/internal/Constants.java b/app/src/main/java/com/obs/services/internal/Constants.java index 01895ae..7e7068e 100644 --- a/app/src/main/java/com/obs/services/internal/Constants.java +++ b/app/src/main/java/com/obs/services/internal/Constants.java @@ -115,6 +115,7 @@ public static class CommonHeaders { public static class ObsRequestParams { public static final String UPLOAD_ID = "uploadId"; public static final String VERSION_ID = "versionId"; + public static final String RULE_ID = "rule-id"; public static final String PREFIX = "prefix"; public static final String MARKER = "marker"; public static final String MAX_KEYS = "max-keys"; @@ -123,6 +124,7 @@ public static class ObsRequestParams { public static final String KEY_MARKER = "key-marker"; public static final String UPLOAD_ID_MARKER = "upload-id-marker"; public static final String VERSION_ID_MARKER = "version-id-marker"; + public static final String RULE_ID_MARKER = "rule-id-marker"; public static final String RESPONSE_CONTENT_TYPE = "response-content-type"; public static final String RESPONSE_CONTENT_LANGUAGE = "response-content-language"; public static final String RESPONSE_EXPIRES = "response-expires"; @@ -144,6 +146,7 @@ public static class ObsRequestParams { public static final String X_CACHE_CONTROL = "x-cache-control"; public static final String TASKID = "taskID"; + public static final String SNAPSHOT_FULL_PATH = "objectKey"; } public static class ObsBucketReplicationRequestParams { @@ -239,7 +242,7 @@ public static class ObsBucketReplicationRequestParams { public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); - public static final String OBS_SDK_VERSION = "3.25.7"; + public static final String OBS_SDK_VERSION = "3.25.10"; public static final String USER_AGENT_VALUE = "obs-sdk-java/" + Constants.OBS_SDK_VERSION; @@ -342,6 +345,7 @@ public static class ObsBucketReplicationRequestParams { "response-cache-control", "response-content-disposition", "response-content-encoding", "x-image-save-bucket", "x-image-save-object", "x-image-process", "x-obs-sse-kms-key-project-id", "x-oss-process", "ignore-sign-in-query", "listcontentsummary", "multilistcontentsummary", - "x-obs-trash", "getcontentsummary", "select", "select-type", "symlink")); + "x-obs-trash", "getcontentsummary", "select", "select-type", "symlink", "x-obs-qosinfo", + "x-obs-snapshot", "x-obs-snapshotroot")); } diff --git a/app/src/main/java/com/obs/services/internal/IConvertor.java b/app/src/main/java/com/obs/services/internal/IConvertor.java index fa85d9c..fd276bc 100644 --- a/app/src/main/java/com/obs/services/internal/IConvertor.java +++ b/app/src/main/java/com/obs/services/internal/IConvertor.java @@ -27,6 +27,7 @@ import com.obs.services.model.GroupGranteeEnum; import com.obs.services.model.KeyAndVersion; import com.obs.services.model.LifecycleConfiguration; +import com.obs.services.model.RenameSnapshotRequest; import com.obs.services.model.ReplicationConfiguration; import com.obs.services.model.RestoreObjectRequest; import com.obs.services.model.StorageClassEnum; @@ -55,6 +56,8 @@ public interface IConvertor { String transStoragePolicy(BucketStoragePolicyConfiguration status) throws ServiceException; + String transCreateSnapshot(String snapshotName) throws ServiceException; + String transBucketLoggingConfiguration(BucketLoggingConfiguration c) throws ServiceException; String transBucketCors(BucketCors cors) throws ServiceException; @@ -87,4 +90,5 @@ String transBucketNotificationConfiguration(BucketNotificationConfiguration buck String transBucketInventoryConfiguration(InventoryConfiguration inventoryConfiguration) throws ServiceException; + String transRenameSnapshot(RenameSnapshotRequest request) throws ServiceException; } \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/internal/ObsConstraint.java b/app/src/main/java/com/obs/services/internal/ObsConstraint.java index e805226..1801d1b 100644 --- a/app/src/main/java/com/obs/services/internal/ObsConstraint.java +++ b/app/src/main/java/com/obs/services/internal/ObsConstraint.java @@ -104,7 +104,7 @@ public class ObsConstraint { public static final long DEFAULT_EXPIRE_SECONEDS = 300; - public static final int DEFAULT_IDLE_CONNECTION_TIME = 30000; + public static final int DEFAULT_IDLE_CONNECTION_TIME = 28000;//28s public static final int DEFAULT_MAX_IDLE_CONNECTIONS = HTTP_MAX_CONNECT_VALUE; @@ -186,6 +186,10 @@ public static class ObsBucketXMLElements { public static final String DOMAINS = "Domains"; } + public static final String SNAPSHOT = "Snapshot"; + public static final String SNAPSHOT_FULL_PATH = "ObjectKey"; + public static final String TAG_SNAPSHOT_DIR = "SnapshottableDir"; + public static final String TAG_SNAPSHOT_DIR_COUNT = "SnapshottableDirCount"; /** * Constants for CustomDomainCertificateConfig validation */ @@ -196,4 +200,30 @@ public static class ObsBucketXMLElements { public static final int CUSTOM_DOMAIN_CERTIFICATE_ID_MAX_LENGTH = 16; public static final int CUSTOM_DOMAIN_CERTIFICATE_MAX_XML_BODY_SIZE_BY_KB = 40; + /** + * Constants for Snapshot validation + */ + public static final int SNAPSHOT_NAME_MAX_LENGTH = 255; + public static final int RULE_ID_MAX_LENGTH = 255; + public static final int SNAPSHOT_FULL_PATH_MAX_LENGTH = 1024; + public static final int SNAPSHOT_MAX_KEYS = 1000; + + public static final String MARKER = "Marker"; + public static final String MAX_KEYS = "MaxKeys"; + public static final String TRUNCATED_CHECK = "IsTruncated"; + public static final String NEXT_MARKER = "NextMarker"; + public static final String ID = "ID"; + public static final String DISPLAY_NAME = "DisplayName"; + public static final String GROUP = "Group"; + public static final String FILE_ID = "FileId"; + public static final String PERMISSION = "Permission"; + public static final String MODIFICATION_TIME = "ModificationTime"; + public static final String SNAPSHOT_QUOTA = "SnapshotQuota"; + public static final String PARENT_FULL_PATH = "ParentFullPath"; + public static final String SNAPSHOT_ENTRY = "SnapshotEntry"; + public static final String SNAPSHOT_COUNT = "SnapshotCount"; + public static final String SNAPSHOT_NAME = "SnapshotName"; + public static final String SNAPSHOT_ID = "SnapshotID"; + public static final String MODIFY_TIME = "ModifyTime"; + public static final String OWNER = "Owner"; } diff --git a/app/src/main/java/com/obs/services/internal/ObsConvertor.java b/app/src/main/java/com/obs/services/internal/ObsConvertor.java index 36b0548..6225c93 100644 --- a/app/src/main/java/com/obs/services/internal/ObsConvertor.java +++ b/app/src/main/java/com/obs/services/internal/ObsConvertor.java @@ -41,6 +41,9 @@ import com.obs.services.model.StorageClassEnum; import com.obs.services.model.TopicConfiguration; +import static com.obs.services.internal.utils.ServiceUtils.escapeXml11; + + public class ObsConvertor extends V2Convertor { private static ObsConvertor instance = new ObsConvertor(); @@ -97,6 +100,17 @@ public String transStoragePolicy(BucketStoragePolicyConfiguration status) throws } } + @Override + public String transCreateSnapshot(String snapshotName) throws ServiceException { + try { + OBSXMLBuilder builder = OBSXMLBuilder.create("SnapshotRequestBody"); + builder.elem("SnapshotName").text(escapeXml11(snapshotName)); + return builder.asString(); + } catch (Exception e) { + throw new ServiceException("Failed to build XML document for SnapshotName", e); + } + } + @Override public String transBucketLoggingConfiguration(BucketLoggingConfiguration c) throws ServiceException { try { diff --git a/app/src/main/java/com/obs/services/internal/ServiceException.java b/app/src/main/java/com/obs/services/internal/ServiceException.java index 08865dd..be1bcbe 100644 --- a/app/src/main/java/com/obs/services/internal/ServiceException.java +++ b/app/src/main/java/com/obs/services/internal/ServiceException.java @@ -48,6 +48,7 @@ public class ServiceException extends RuntimeException { private String requestPath; private String requestHost; private String errorIndicator; + private String encodedAuthorizationMessage; public ServiceException(String message, String xmlMessage) { this(message, xmlMessage, null); @@ -125,6 +126,7 @@ private void parseXmlMessage(String xmlMessage) { if (errorDetails != null && errorDetails.length() > 0) { this.errorMessage += " " + errorDetails; } + this.encodedAuthorizationMessage = findXmlElementText(xmlMessage,"EncodedAuthorizationMessage"); } @@ -247,4 +249,12 @@ public void setErrorIndicator(String errorIndicator) { this.errorIndicator = errorIndicator; } + public String getEncodedAuthorizationMessage() { + return this.encodedAuthorizationMessage; + } + + public void setEncodedAuthorizationMessage(String encodedAuthorizationMessage) { + this.encodedAuthorizationMessage = encodedAuthorizationMessage; + } + } diff --git a/app/src/main/java/com/obs/services/internal/V2BucketConvertor.java b/app/src/main/java/com/obs/services/internal/V2BucketConvertor.java index f05138f..f79f2f4 100644 --- a/app/src/main/java/com/obs/services/internal/V2BucketConvertor.java +++ b/app/src/main/java/com/obs/services/internal/V2BucketConvertor.java @@ -37,6 +37,7 @@ import com.obs.services.model.GranteeInterface; import com.obs.services.model.GroupGrantee; import com.obs.services.model.Permission; +import com.obs.services.model.RenameSnapshotRequest; import com.obs.services.model.SSEAlgorithmEnum; import com.obs.services.model.TopicConfiguration; import com.obs.services.model.fs.FSStatusEnum; @@ -356,4 +357,6 @@ public String transBucketInventoryConfiguration(InventoryConfiguration inventory throw new ServiceException("Failed to build XML document for InventoryConfiguration", e); } } + + public abstract String transRenameSnapshot(RenameSnapshotRequest request) throws ServiceException; } diff --git a/app/src/main/java/com/obs/services/internal/V2Convertor.java b/app/src/main/java/com/obs/services/internal/V2Convertor.java index d99fc19..4d48846 100644 --- a/app/src/main/java/com/obs/services/internal/V2Convertor.java +++ b/app/src/main/java/com/obs/services/internal/V2Convertor.java @@ -17,6 +17,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; +import java.util.function.Consumer; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; @@ -39,6 +40,7 @@ import com.obs.services.model.Owner; import com.obs.services.model.Permission; import com.obs.services.model.Redirect; +import com.obs.services.model.RenameSnapshotRequest; import com.obs.services.model.ReplicationConfiguration; import com.obs.services.model.RestoreObjectRequest; import com.obs.services.model.RouteRule; @@ -47,6 +49,9 @@ import com.obs.services.model.WebsiteConfiguration; import com.obs.services.model.BucketTagInfo; +import static com.obs.services.internal.utils.ServiceUtils.escapeXml11; + + public class V2Convertor extends V2BucketConvertor { private static IConvertor instance = new V2Convertor(); @@ -315,6 +320,32 @@ public String transStoragePolicy(BucketStoragePolicyConfiguration status) throws } } + private String buildSnapshotXML(Consumer builderConfigurer, String operation) throws ServiceException { + try { + OBSXMLBuilder builder = OBSXMLBuilder.create("SnapshotRequestBody"); + builderConfigurer.accept(builder); + return builder.asString(); + } catch (Exception e) { + throw new ServiceException("Failed to build XML document for " + operation, e); + } + } + + @Override + public String transCreateSnapshot(String snapshotName) throws ServiceException { + return buildSnapshotXML(builder -> + builder.elem("SnapshotName").text(escapeXml11(snapshotName)), + "CreateSnapshotRequest" + ); + } + + @Override + public String transRenameSnapshot(RenameSnapshotRequest request) throws ServiceException { + return buildSnapshotXML(builder -> { + builder.elem("SnapshotName").text(escapeXml11(request.getOldSnapshotName())); + builder.elem("NewSnapshotName").text(escapeXml11(request.getNewSnapshotName())); + }, "RenameSnapshotRequest"); + } + @Override public String transAccessControlList(AccessControlList acl, boolean isBucket) throws ServiceException { Owner owner = acl.getOwner(); diff --git a/app/src/main/java/com/obs/services/internal/handler/XmlResponsesSaxParser.java b/app/src/main/java/com/obs/services/internal/handler/XmlResponsesSaxParser.java index a3159aa..665c7f2 100644 --- a/app/src/main/java/com/obs/services/internal/handler/XmlResponsesSaxParser.java +++ b/app/src/main/java/com/obs/services/internal/handler/XmlResponsesSaxParser.java @@ -15,8 +15,28 @@ package com.obs.services.internal.handler; import static com.obs.services.internal.ObsConstraint.CERTIFICATE_ID; +import static com.obs.services.internal.ObsConstraint.DISPLAY_NAME; +import static com.obs.services.internal.ObsConstraint.FILE_ID; +import static com.obs.services.internal.ObsConstraint.GROUP; +import static com.obs.services.internal.ObsConstraint.ID; +import static com.obs.services.internal.ObsConstraint.MARKER; +import static com.obs.services.internal.ObsConstraint.MAX_KEYS; +import static com.obs.services.internal.ObsConstraint.MODIFICATION_TIME; +import static com.obs.services.internal.ObsConstraint.MODIFY_TIME; +import static com.obs.services.internal.ObsConstraint.NEXT_MARKER; +import static com.obs.services.internal.ObsConstraint.OWNER; import static com.obs.services.internal.ObsConstraint.ObsBucketXMLElements.CREATE_TIME; import static com.obs.services.internal.ObsConstraint.ObsBucketXMLElements.DOMAINS; +import static com.obs.services.internal.ObsConstraint.PARENT_FULL_PATH; +import static com.obs.services.internal.ObsConstraint.PERMISSION; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_COUNT; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_ENTRY; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_ID; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_NAME; +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_QUOTA; +import static com.obs.services.internal.ObsConstraint.TAG_SNAPSHOT_DIR; +import static com.obs.services.internal.ObsConstraint.TAG_SNAPSHOT_DIR_COUNT; +import static com.obs.services.internal.ObsConstraint.TRUNCATED_CHECK; import static com.obs.services.internal.xml.BucketTrashConfigurationXMLBuilder.RESERVED_DAYS; import static com.obs.services.model.bpa.BucketPolicyStatus.POLICY_STATUS; import static com.obs.services.model.bpa.BucketPublicAccessBlock.BLOCK_PUBLIC_ACLS; @@ -34,6 +54,13 @@ import com.obs.services.model.AbstractNotification; import com.obs.services.model.AccessControlList; import com.obs.services.model.ObjectTypeEnum; +import com.obs.services.model.Qos.QosRule; +import com.obs.services.model.Qos.GetBucketQoSResult; +import com.obs.services.model.Qos.QpsLimitConfiguration; +import com.obs.services.model.Qos.BpsLimitConfiguration; +import com.obs.services.model.Qos.NetworkType; +import com.obs.services.model.Snapshot; +import com.obs.services.model.SnapshottableDir; import com.obs.services.model.bpa.BucketPolicyStatus; import com.obs.services.model.bpa.BucketPublicAccessBlock; import com.obs.services.model.bpa.BucketPublicStatus; @@ -109,6 +136,8 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; +import java.util.Locale; + import com.obs.services.model.ObjectTagResult; public class XmlResponsesSaxParser { @@ -2849,4 +2878,346 @@ public void endElement(String name, String content) { } } } + + public static class BucketQosConfigurationHandler extends DefaultXmlHandler { + + // 解析结果对象 + protected GetBucketQoSResult result; + + // 临时存储当前解析的对象 + private QosRule currentQosRule; + private QpsLimitConfiguration currentQpsLimit; + private BpsLimitConfiguration currentBpsLimit; + + // 核心标记:当前是否在QoSGroupConfiguration内部 + private boolean isInGroupConfig = false; + + public GetBucketQoSResult getQosResult() { + return result; + } + + @Override + public void startElement(String name) { + // 初始化结果对象 + if ("GetBucketQoSResponse".equals(name)) { + result = new GetBucketQoSResult(); + return; + } + + // 进入QoSGroupConfiguration区域,标记为true + if ("QoSGroupConfiguration".equals(name)) { + isInGroupConfig = true; + return; + } + + // 初始化QoS规则对象 + if ("QoSRule".equals(name)) { + currentQosRule = new QosRule(null, 0, null, null); + } else if ("QpsLimit".equals(name)) { + currentQpsLimit = new QpsLimitConfiguration(0, 0, 0, 0); + } else if ("BpsLimit".equals(name)) { + currentBpsLimit = new BpsLimitConfiguration(0, 0, 0); + } + } + + @Override + public void endElement(String name, String content) { + if (result == null) { + return; + } + + // 离开QoSGroupConfiguration区域,标记为false + if ("QoSGroupConfiguration".equals(name)) { + isInGroupConfig = false; + return; + } + + // 解析QoS组名称 + if ("QoSGroup".equals(name)) { + result.setQosGroup(content.trim()); + return; + } + + // 处理QpsLimit的子元素 + if (currentQpsLimit != null && !"QpsLimit".equals(name)) { + long value = parseAndLogLong(name, content); + switch (name) { + case "Get": + currentQpsLimit.setQpsGetLimit(value); + break; + case "PutPostDelete": + currentQpsLimit.setQpsPutPostDeleteLimit(value); + break; + case "List": + currentQpsLimit.setQpsListLimit(value); + break; + case "Total": + currentQpsLimit.setQpsTotalLimit(value); + break; + default: + break; + } + return; + } + + // 处理BpsLimit的子元素 + if (currentBpsLimit != null && !"BpsLimit".equals(name)) { + long value = parseAndLogLong(name, content); + switch (name) { + case "Get": + currentBpsLimit.setBpsGetLimit(value); + break; + case "PutPost": + currentBpsLimit.setBpsPutPostLimit(value); + break; + case "Total": + currentBpsLimit.setBpsTotalLimit(value); + break; + default: + break; + } + return; + } + + // 处理QoSRule的子元素和结束标签 + if (currentQosRule != null) { + switch (name) { + case "NetworkType": + currentQosRule.setNetworkType(parseNetworkType(content)); + break; + case "ConcurrentRequestLimit": + currentQosRule.setConcurrentRequestLimit(parseAndLogLong(name, content)); + break; + case "QpsLimit": + currentQosRule.setQpsLimit(currentQpsLimit); + currentQpsLimit = null; + break; + case "BpsLimit": + currentQosRule.setBpsLimit(currentBpsLimit); + currentBpsLimit = null; + break; + case "QoSRule": + // 根据boolean标记决定加入哪个列表 + if (isInGroupConfig) { + result.getGroupQosRules().add(currentQosRule); + } else { + result.getBucketQosRules().add(currentQosRule); + } + currentQosRule = null; + break; + default: + break; + } + } + } + + private NetworkType parseNetworkType(String content) { + try { + return NetworkType.valueOf(content.trim().toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + log.error("Invalid NetworkType value: " + content, e); + return null; + } + } + + private long parseAndLogLong(String name, String content) { + try { + return Long.parseLong(content.trim()); + } catch (NumberFormatException e) { + log.error("Failed to parse long value for " + name + " " + content, e); + return 0; + } + } + } + public static abstract class BasePaginatedHandler extends DefaultXmlHandler { + protected String marker; + protected String nextMarker; + protected boolean truncated; + protected int maxKeys; + + public boolean isTruncated() { + return truncated; + } + + public String getMarker() { + return marker; + } + + public int getMaxKeys() { + return maxKeys; + } + + public String getNextMarker() { + return nextMarker; + } + + protected void handleCommonPaginationElements(String name, String elementText) { + switch (name) { + case MARKER: + marker = elementText; + break; + case MAX_KEYS: + maxKeys = parseIntWithWarning(elementText, "maxKeys"); + break; + case TRUNCATED_CHECK: + truncated = Boolean.parseBoolean(elementText); + break; + case NEXT_MARKER: + nextMarker = elementText; + break; + } + } + + protected int parseIntWithWarning(String elementText, String fieldName) { + try { + return Integer.parseInt(elementText); + } catch (NumberFormatException e) { + if (log.isWarnEnabled()) { + log.warn("Failed to parse Integer for " + fieldName + ": " + elementText, e); + } + return 0; + } + } + + protected long parseLongWithWarning(String elementText, String fieldName) { + try { + return Long.parseLong(elementText); + } catch (NumberFormatException e) { + if (log.isWarnEnabled()) { + log.warn("Failed to parse Long for " + fieldName + ": " + elementText, e); + } + return 0L; + } + } + } + + public static class GetSnapshottableDirListHandler extends BasePaginatedHandler { + private Owner bucketsOwner; + private int snapshottableDirCount; + private SnapshottableDir currentSnapshottableDir; + private List snapshottableDir = new ArrayList<>(); + + public List getSnapshottableDirs() { + return this.snapshottableDir; + } + + public Owner getOwner() { + return bucketsOwner; + } + + public int getSnapshottableDirCount() { + return snapshottableDirCount; + } + + @Override + public void startElement(String name) { + if (name.equals(TAG_SNAPSHOT_DIR)) { + currentSnapshottableDir = new SnapshottableDir(); + } else if (name.equals(OWNER)) { + bucketsOwner = new Owner(); + } + } + + @Override + public void endElement(String name, String elementText) { + handleCommonPaginationElements(name, elementText); + + if (name.equals(TAG_SNAPSHOT_DIR_COUNT)) { + snapshottableDirCount = parseIntWithWarning(elementText, "snapshottableDirCount"); + return; + } + + if (bucketsOwner != null) { + if (name.equals(ID)) { + bucketsOwner.setId(elementText); + return; + } else if (name.equals(DISPLAY_NAME)) { + bucketsOwner.setDisplayName(elementText); + return; + } + } + + if (currentSnapshottableDir != null) { + switch (name) { + case TAG_SNAPSHOT_DIR: + currentSnapshottableDir.setOwner(bucketsOwner); + snapshottableDir.add(currentSnapshottableDir); + break; + case GROUP: + currentSnapshottableDir.setGroup(elementText); + break; + case FILE_ID: + currentSnapshottableDir.setFileId(elementText); + break; + case PERMISSION: + currentSnapshottableDir.setPermission(elementText); + break; + case MODIFICATION_TIME: + long modTime = parseLongWithWarning(elementText, "modificationTime"); + if (modTime > 0) { + currentSnapshottableDir.setModificationTime(new Date(modTime)); + } + break; + case SNAPSHOT_QUOTA: + int quota = parseIntWithWarning(elementText, "snapshotQuota"); + currentSnapshottableDir.setSnapshotQuota(quota); + break; + case PARENT_FULL_PATH: + currentSnapshottableDir.setParentFullPath(elementText); + break; + } + } + } + } + + public static class GetSnapshotListHandler extends BasePaginatedHandler { + private int snapshotCount; + private Snapshot currentSnapshot; + private List snapshotList = new ArrayList<>(); + + public List getSnapshots() { + return this.snapshotList; + } + + public int getSnapshotCount() { + return snapshotCount; + } + + @Override + public void startElement(String name) { + if (name.equals(SNAPSHOT_ENTRY)) { + currentSnapshot = new Snapshot(); + } + } + + @Override + public void endElement(String name, String elementText) { + handleCommonPaginationElements(name, elementText); + + if (name.equals(SNAPSHOT_COUNT)) { + snapshotCount = parseIntWithWarning(elementText, "snapshotCount"); + return; + } + + if (currentSnapshot != null) { + switch (name) { + case SNAPSHOT_ENTRY: + snapshotList.add(currentSnapshot); + break; + case SNAPSHOT_NAME: + currentSnapshot.setSnapshotName(elementText); + break; + case SNAPSHOT_ID: + currentSnapshot.setSnapshotID(elementText); + break; + case MODIFY_TIME: + long modifyTime = parseLongWithWarning(elementText, "modifyTime"); + if (modifyTime > 0) { + currentSnapshot.setModifyTime(new Date(modifyTime)); + } + break; + } + } + } + } } diff --git a/app/src/main/java/com/obs/services/internal/service/ObsBucketAdvanceService.java b/app/src/main/java/com/obs/services/internal/service/ObsBucketAdvanceService.java index a622ab0..de6d5be 100644 --- a/app/src/main/java/com/obs/services/internal/service/ObsBucketAdvanceService.java +++ b/app/src/main/java/com/obs/services/internal/service/ObsBucketAdvanceService.java @@ -34,8 +34,15 @@ import com.obs.services.internal.xml.CustomDomainCertificateConfigXMLBuilder; import com.obs.services.internal.xml.OBSXMLBuilder; import com.obs.services.internal.xml.BucketTrashConfigurationXMLBuilder; +import com.obs.services.internal.xml.QosConfigurationXMLBuilder; import com.obs.services.model.AccessControlList; import com.obs.services.model.AuthTypeEnum; +import com.obs.services.model.DeleteBucketLifecycleRequest; +import com.obs.services.model.GetBucketLifecycleRequest; +import com.obs.services.model.Qos.SetBucketQosRequest; +import com.obs.services.model.Qos.GetBucketQoSRequest; +import com.obs.services.model.Qos.GetBucketQoSResult; +import com.obs.services.model.Qos.DeleteBucketQosRequest; import com.obs.services.model.bpa.BucketPublicAccessBlock; import com.obs.services.model.bpa.BucketPublicStatus; import com.obs.services.model.bpa.DeleteBucketPublicAccessBlockRequest; @@ -103,7 +110,6 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; - import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -261,6 +267,11 @@ protected HeaderResponse setBucketLifecycleConfigurationImpl(SetBucketLifecycleR throws ServiceException { Map requestParams = new HashMap<>(); requestParams.put(SpecialParamEnum.LIFECYCLE.getOriginalStringCode(), ""); + if (request.getRuleId() != null) { + ServiceUtils.checkParameterLength(Constants.ObsRequestParams.RULE_ID, request.getRuleId(), + 1, ObsConstraint.RULE_ID_MAX_LENGTH); + requestParams.put(Constants.ObsRequestParams.RULE_ID, request.getRuleId()); + } Map headers = new HashMap<>(); String xml = this.getIConvertor(request.getBucketName()) @@ -294,6 +305,33 @@ protected LifecycleConfiguration getBucketLifecycleConfigurationImpl(BaseBucketR return ret; } + protected LifecycleConfiguration getBucketLifecycleConfigurationImpl(GetBucketLifecycleRequest request) + throws ServiceException { + Map requestParameters = new HashMap<>(); + requestParameters.put(SpecialParamEnum.LIFECYCLE.getOriginalStringCode(), ""); + if (request.getRuleId() != null) { + ServiceUtils.checkParameterLength(Constants.ObsRequestParams.RULE_ID, request.getRuleId(), + 1, ObsConstraint.RULE_ID_MAX_LENGTH); + requestParameters.put(Constants.ObsRequestParams.RULE_ID, request.getRuleId()); + } + if (request.getRuleIdMarker() != null) { + ServiceUtils.checkParameterLength(Constants.ObsRequestParams.RULE_ID_MARKER, request.getRuleIdMarker(), + 1, ObsConstraint.RULE_ID_MAX_LENGTH); + requestParameters.put(Constants.ObsRequestParams.RULE_ID_MARKER, request.getRuleIdMarker()); + } + + Response response = performRestGet(request.getBucketName(), null, requestParameters, + transRequestPaymentHeaders(request, null, this.getIHeaders(request.getBucketName())), + request.getUserHeaders()); + + this.verifyResponseContentType(response); + + LifecycleConfiguration ret = getXmlResponseSaxParser().parse(new HttpMethodReleaseInputStream(response), + XmlResponsesSaxParser.BucketLifecycleConfigurationHandler.class, false).getLifecycleConfig(); + setHeadersAndStatus(ret, response); + return ret; + } + protected HeaderResponse deleteBucketLifecycleConfigurationImpl(BaseBucketRequest request) throws ServiceException { Map requestParameters = new HashMap<>(); requestParameters.put(SpecialParamEnum.LIFECYCLE.getOriginalStringCode(), ""); @@ -303,6 +341,20 @@ protected HeaderResponse deleteBucketLifecycleConfigurationImpl(BaseBucketReques return build(response); } + protected HeaderResponse deleteBucketLifecycleConfigurationImpl(DeleteBucketLifecycleRequest request) throws ServiceException { + Map requestParameters = new HashMap<>(); + requestParameters.put(SpecialParamEnum.LIFECYCLE.getOriginalStringCode(), ""); + if (request.getRuleId() != null) { + ServiceUtils.checkParameterLength(Constants.ObsRequestParams.RULE_ID, request.getRuleId(), + 1, ObsConstraint.RULE_ID_MAX_LENGTH); + requestParameters.put(Constants.ObsRequestParams.RULE_ID, request.getRuleId()); + } + Response response = performRestDelete(request.getBucketName(), null, requestParameters, + transRequestPaymentHeaders(request, null, this.getIHeaders(request.getBucketName())), + request.getUserHeaders()); + return build(response); + } + protected HeaderResponse setBucketTaggingImpl(SetBucketTaggingRequest request) throws ServiceException { Map requestParams = new HashMap<>(); requestParams.put(SpecialParamEnum.TAGGING.getOriginalStringCode(), ""); @@ -1129,4 +1181,53 @@ protected GetBucketPublicStatusResult getBucketPublicStatusImpl(GetBucketPublicS getBucketPublicAccessBlockResult.setBucketPublicStatus(bucketPolicyStatus); return getBucketPublicAccessBlockResult; } + + protected HeaderResponse setBucketQosImpl(SetBucketQosRequest request){ + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.BUCKET_QOS.getOriginalStringCode(), ""); + Map headers = new HashMap<>(); + transRequestPaymentHeaders(request, headers,this.getIHeaders(request.getBucketName())); + + QosConfigurationXMLBuilder xmlBuilder = new QosConfigurationXMLBuilder(); + String xml = xmlBuilder.buildXML(request.getQosConfig()); + + headers.put(CommonHeaders.CONTENT_TYPE, Mimetypes.MIMETYPE_XML); + headers.put(CommonHeaders.CONTENT_LENGTH, String.valueOf(xml.length())); + headers.put(CommonHeaders.CONTENT_MD5, ServiceUtils.computeMD5(xml)); + + if (log.isTraceEnabled()) { + log.trace("setBucketQosRequest's xml is:"); + log.trace(xml); + } + NewTransResult transResult = transRequest(request); + transResult.setHeaders(headers); + transResult.setParams(requestParams); + transResult.setBody(createRequestBody(Mimetypes.MIMETYPE_XML, xml)); + + Response response = performRequest(transResult,true,false,false,false); + return build(response); + } + + protected GetBucketQoSResult getBucketQosImpl(GetBucketQoSRequest request){ + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.BUCKET_QOS.getOriginalStringCode(), ""); + Response response = performRestGet(request.getBucketName(),null,requestParams, + transRequestPaymentHeaders(request,null,this.getIHeaders(request.getBucketName())), + request.getUserHeaders()); + this.verifyResponseContentType(response); + + GetBucketQoSResult ret = getXmlResponseSaxParser().parse(new HttpMethodReleaseInputStream(response), + XmlResponsesSaxParser.BucketQosConfigurationHandler.class, false).getQosResult(); + setHeadersAndStatus(ret, response); + return ret; + } + + protected HeaderResponse deleteBucketQosImpl(DeleteBucketQosRequest request){ + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.BUCKET_QOS.getOriginalStringCode(), ""); + Response response = performRestDelete(request.getBucketName(), null, requestParams, + transRequestPaymentHeaders(request, null, this.getIHeaders(request.getBucketName())), + request.getUserHeaders()); + return this.build(response); + } } diff --git a/app/src/main/java/com/obs/services/internal/service/ObsBucketBaseService.java b/app/src/main/java/com/obs/services/internal/service/ObsBucketBaseService.java index 84b52b0..3fa8876 100644 --- a/app/src/main/java/com/obs/services/internal/service/ObsBucketBaseService.java +++ b/app/src/main/java/com/obs/services/internal/service/ObsBucketBaseService.java @@ -20,7 +20,6 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; -import java.util.ArrayList; import com.obs.log.ILogger; import com.obs.log.LoggerBuilder; @@ -34,6 +33,8 @@ import com.obs.services.internal.utils.ServiceUtils; import com.obs.services.model.AccessControlList; import com.obs.services.model.BaseBucketRequest; +import com.obs.services.model.BaseObjectRequest; +import com.obs.services.model.BaseSnapshotRequest; import com.obs.services.model.BucketLocationResponse; import com.obs.services.model.BucketMetadataInfoRequest; import com.obs.services.model.BucketMetadataInfoResult; @@ -42,6 +43,13 @@ import com.obs.services.model.BucketStoragePolicyConfiguration; import com.obs.services.model.BucketVersioningConfiguration; import com.obs.services.model.CreateBucketRequest; +import com.obs.services.model.CreateSnapshotRequest; +import com.obs.services.model.CreateSnapshotResponse; +import com.obs.services.model.DeleteSnapshotRequest; +import com.obs.services.model.GetSnapshottableDirListRequest; +import com.obs.services.model.GetSnapshottableDirListResult; +import com.obs.services.model.GetSnapshotListRequest; +import com.obs.services.model.GetSnapshotListResponse; import com.obs.services.model.HeaderResponse; import com.obs.services.model.HttpMethodEnum; import com.obs.services.model.ListBucketsRequest; @@ -52,8 +60,12 @@ import com.obs.services.model.ObjectListing; import com.obs.services.model.ObsBucket; import com.obs.services.model.OptionsInfoRequest; +import com.obs.services.model.RenameSnapshotRequest; +import com.obs.services.model.RenameSnapshotResponse; import com.obs.services.model.SetBucketPolicyRequest; import com.obs.services.model.SetBucketStoragePolicyRequest; +import com.obs.services.model.SetDisallowSnapshotRequest; +import com.obs.services.model.SetSnapshotAllowRequest; import com.obs.services.model.SpecialParamEnum; import com.obs.services.model.VersionOrDeleteMarker; import com.obs.services.model.fs.GetBucketFSStatusResult; @@ -67,7 +79,11 @@ import com.obs.services.model.inventory.GetInventoryConfigurationResult; import com.obs.services.model.inventory.ListInventoryConfigurationResult; import okhttp3.Response; -import okhttp3.internal.http.HttpMethod; + +import static com.obs.services.internal.Constants.ObsRequestParams.MARKER; +import static com.obs.services.internal.Constants.ObsRequestParams.MAX_KEYS; +import static com.obs.services.internal.Constants.ObsRequestParams.SNAPSHOT_FULL_PATH; + public abstract class ObsBucketBaseService extends RequestConvertor { @@ -123,10 +139,10 @@ protected ListBucketsResult listAllBucketsImpl(ListBucketsRequest request) throw this.putHeader(headers, this.getIHeaders("").bucketTypeHeader(), request.getBucketType().getCode()); } if (request.getMaxKeys() > 0) { - params.put(Constants.ObsRequestParams.MAX_KEYS, String.valueOf(request.getMaxKeys())); + params.put(MAX_KEYS, String.valueOf(request.getMaxKeys())); } if (request.getMarker() != null) { - params.put(Constants.ObsRequestParams.MARKER, request.getMarker()); + params.put(MARKER, request.getMarker()); } } @@ -469,13 +485,13 @@ protected GetInventoryConfigurationResult getInventoryConfigurationImpl(GetInven NewTransResult newTransResult = transRequest(request); newTransResult.setParams(requestParams); - Response httpResponse = performRequest(newTransResult, true,false,false,false); + Response httpResponse = performRequest(newTransResult, true, false, false, false); this.verifyResponseContentType(httpResponse); GetInventoryConfigurationResult result = new GetInventoryConfigurationResult(); List configurations = getXmlResponseSaxParser().parse(new HttpMethodReleaseInputStream(httpResponse), XmlResponsesSaxParser.InventoryConfigurationsHandler.class, false).getInventoryConfigurations(); - if(configurations == null || configurations.isEmpty()) { + if (configurations == null || configurations.isEmpty()) { log.warn("No configuration got, config id is :" + request.getConfigurationId()); } else { result.setInventoryConfiguration(configurations.get(0)); @@ -490,7 +506,7 @@ protected ListInventoryConfigurationResult listInventoryConfigurationImpl(ListIn NewTransResult newTransResult = transRequest(request); newTransResult.setParams(requestParams); - Response httpResponse = performRequest(newTransResult, true,false,false,false); + Response httpResponse = performRequest(newTransResult, true, false, false, false); this.verifyResponseContentType(httpResponse); ListInventoryConfigurationResult result = new ListInventoryConfigurationResult(); @@ -508,8 +524,140 @@ protected HeaderResponse deleteInventoryConfigurationImpl(DeleteInventoryConfigu NewTransResult newTransResult = transRequest(request); newTransResult.setParams(requestParams); - Response httpResponse = performRequest(newTransResult, true,false,false,false); + Response httpResponse = performRequest(newTransResult, true, false, false, false); + + return build(httpResponse); + } + + private HeaderResponse processSnapshotRequest(BaseObjectRequest request) throws ServiceException { + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.OBS_SNAPSHOT_ROOT.getOriginalStringCode(), ""); + + NewTransResult newTransResult = transObjectRequest(request); + newTransResult.setParams(requestParams); + Response httpResponse = performRequest(newTransResult); return build(httpResponse); } + + protected HeaderResponse setSnapshotAllowImpl(SetSnapshotAllowRequest request) throws ServiceException { + return processSnapshotRequest(request); + } + + protected HeaderResponse setDisallowSnapshotImpl(SetDisallowSnapshotRequest request) throws ServiceException { + return processSnapshotRequest(request); + } + + protected GetSnapshottableDirListResult getSnapshottableDirListImpl(GetSnapshottableDirListRequest request) throws ServiceException { + NewTransResult newTransResult = transGetSnapshottableDirListRequest(request); + Response httpResponse = performRequest(newTransResult, true, false, false, false); + + this.verifyResponseContentType(httpResponse); + + XmlResponsesSaxParser.GetSnapshottableDirListHandler handler = getXmlResponseSaxParser().parse( + new HttpMethodReleaseInputStream(httpResponse), XmlResponsesSaxParser.GetSnapshottableDirListHandler.class, true); + + GetSnapshottableDirListResult getSnapshottableDirListResult = new GetSnapshottableDirListResult(handler.getMarker(), handler.getNextMarker(), + handler.isTruncated(), handler.getMaxKeys(), handler.getSnapshottableDirCount(), handler.getSnapshottableDirs()); + setHeadersAndStatus(getSnapshottableDirListResult, httpResponse); + + return getSnapshottableDirListResult; + } + + protected GetSnapshotListResponse getSnapshotListImpl(GetSnapshotListRequest request) throws ServiceException { + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.OBS_SNAPSHOT.getOriginalStringCode(), ""); + + if (ServiceUtils.isValid(request.getObjectKey())) { + requestParams.put(SNAPSHOT_FULL_PATH, request.getObjectKey()); + } + + if (ServiceUtils.isValid(request.getMarker())) { + requestParams.put(MARKER, request.getMarker()); + } + + if (request.getMaxKeys() > 0) { + requestParams.put(MAX_KEYS, String.valueOf(request.getMaxKeys())); + } + + NewTransResult newTransResult = transObjectRequest(request); + newTransResult.setParams(requestParams); + Response httpResponse = performRequest(newTransResult, true, false, false, false); + XmlResponsesSaxParser.GetSnapshotListHandler handler = getXmlResponseSaxParser().parse( + new HttpMethodReleaseInputStream(httpResponse), XmlResponsesSaxParser.GetSnapshotListHandler.class, false); + + GetSnapshotListResponse getSnapshotListResponse = new GetSnapshotListResponse(handler.getMarker(), handler.getNextMarker(), + handler.isTruncated(), handler.getMaxKeys(), handler.getSnapshotCount(), handler.getSnapshots()); + setHeadersAndStatus(getSnapshotListResponse, httpResponse); + + return getSnapshotListResponse; + } + + + + /** + * Internal implementation of renameSnapshot + */ + protected RenameSnapshotResponse renameSnapshotImpl(RenameSnapshotRequest request) throws ServiceException { + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.OBS_SNAPSHOT.getOriginalStringCode(), ""); + + + Map headers = new HashMap<>(); + transRequestPaymentHeaders(request, headers, this.getIHeaders(request.getBucketName())); + headers.put(CommonHeaders.CONTENT_TYPE, Mimetypes.MIMETYPE_XML); + + String xml; + if (request.getOldSnapshotName() == null || request.getNewSnapshotName() == null) { + log.warn("Snapshot rename operation skipped - missing snapshot names. OldSnapshotName: " + + request.getOldSnapshotName() + ", NewSnapshotName: " + request.getNewSnapshotName()); + xml = ""; + } else { + xml = this.getIConvertor(request.getBucketName()).transRenameSnapshot(request); + } + + NewTransResult newTransResult = transObjectRequest(request); + newTransResult.setParams(requestParams); + newTransResult.setHeaders(headers); + newTransResult.setBody(createRequestBody(Mimetypes.MIMETYPE_XML, xml)); + + Response httpResponse = performRequest(newTransResult); + RenameSnapshotResponse result = new RenameSnapshotResponse(); + setHeadersAndStatus(result, httpResponse); + return result; + } + + protected CreateSnapshotResponse createSnapshotImpl(CreateSnapshotRequest request) throws ServiceException { + Response httpResponse = executeSnapshotRequest(request); + CreateSnapshotResponse result = new CreateSnapshotResponse(); + setHeadersAndStatus(result, httpResponse); + return result; + } + + protected HeaderResponse deleteSnapshotImpl(DeleteSnapshotRequest request) throws ServiceException { + Response httpResponse = executeSnapshotRequest(request); + return build(httpResponse); + } + + private Response executeSnapshotRequest(BaseSnapshotRequest request) throws ServiceException { + Map requestParams = new HashMap<>(); + requestParams.put(SpecialParamEnum.OBS_SNAPSHOT.getOriginalStringCode(), ""); + + if (request instanceof CreateSnapshotRequest) { + requestParams.put("snapshotName", request.getSnapshotName()); + } + + Map headers = new HashMap<>(); + transRequestPaymentHeaders(request, headers, this.getIHeaders(request.getBucketName())); + headers.put(CommonHeaders.CONTENT_TYPE, Mimetypes.MIMETYPE_XML); + + String xml = this.getIConvertor(request.getBucketName()).transCreateSnapshot(request.getSnapshotName()); + + NewTransResult newTransResult = transObjectRequest(request); + newTransResult.setParams(requestParams); + newTransResult.setHeaders(headers); + newTransResult.setBody(createRequestBody(Mimetypes.MIMETYPE_XML, xml)); + + return performRequest(newTransResult); + } } diff --git a/app/src/main/java/com/obs/services/internal/service/RequestConvertor.java b/app/src/main/java/com/obs/services/internal/service/RequestConvertor.java index 765356d..19ee9c1 100644 --- a/app/src/main/java/com/obs/services/internal/service/RequestConvertor.java +++ b/app/src/main/java/com/obs/services/internal/service/RequestConvertor.java @@ -46,6 +46,7 @@ import com.obs.services.model.ExtensionBucketPermissionEnum; import com.obs.services.model.ExtensionObjectPermissionEnum; import com.obs.services.model.GetObjectRequest; +import com.obs.services.model.GetSnapshottableDirListRequest; import com.obs.services.model.InitiateMultipartUploadRequest; import com.obs.services.model.ListObjectsRequest; import com.obs.services.model.ListVersionsRequest; @@ -871,6 +872,26 @@ protected TransResult transListObjectsRequest(ListObjectsRequest listObjectsRequ return new TransResult(headers, params, null); } + protected NewTransResult transGetSnapshottableDirListRequest(GetSnapshottableDirListRequest getSnapshottableDirListRequest) { + Map params = new HashMap(); + + params.put(SpecialParamEnum.OBS_SNAPSHOT_ROOT.getOriginalStringCode(), ""); + if (getSnapshottableDirListRequest.getMaxKeys() > 0) { + params.put(ObsRequestParams.MAX_KEYS, String.valueOf(getSnapshottableDirListRequest.getMaxKeys())); + } + if (getSnapshottableDirListRequest.getMarker() != null) { + params.put(ObsRequestParams.MARKER, getSnapshottableDirListRequest.getMarker()); + } + + Map headers = new HashMap(); + transRequestPaymentHeaders(getSnapshottableDirListRequest, headers, this.getIHeaders(getSnapshottableDirListRequest.getBucketName())); + + NewTransResult result = transRequest(getSnapshottableDirListRequest); + result.setParams(params); + result.setHeaders(headers); + return result; + } + protected TransResult transListContentSummaryRequest(ListContentSummaryRequest listContentSummaryRequest) { Map params = new HashMap(); if (listContentSummaryRequest.getPrefix() != null) { diff --git a/app/src/main/java/com/obs/services/internal/utils/Mimetypes.java b/app/src/main/java/com/obs/services/internal/utils/Mimetypes.java index 40d06a3..9a7353c 100644 --- a/app/src/main/java/com/obs/services/internal/utils/Mimetypes.java +++ b/app/src/main/java/com/obs/services/internal/utils/Mimetypes.java @@ -101,7 +101,7 @@ private static void addApplicationXMimetypeOne(Map extensionToMi extensionToMimetypeMap.put("7z", "application/x-7z-compressed"); extensionToMimetypeMap.put("deb", "application/x-debian-package"); extensionToMimetypeMap.put("wmz", "application/x-ms-wmz"); - extensionToMimetypeMap.put("woff", "application/x-font-woff"); + extensionToMimetypeMap.put("woff", "application/font-woff"); extensionToMimetypeMap.put("xap", "application/x-silverlight-app"); extensionToMimetypeMap.put("man", "application/x-troff-man"); extensionToMimetypeMap.put("mfp", "application/x-shockwave-flash"); @@ -118,9 +118,9 @@ private static void addApplicationXMimetypeOne(Map extensionToMi extensionToMimetypeMap.put("wmd", "application/x-ms-wmd"); extensionToMimetypeMap.put("exe", "application/x-msdownload"); extensionToMimetypeMap.put("dll", "application/x-msdownload"); - extensionToMimetypeMap.put("js", "application/x-javascript"); - extensionToMimetypeMap.put("mocha", "application/x-javascript"); - extensionToMimetypeMap.put("ls", "application/x-javascript"); + extensionToMimetypeMap.put("js", "application/javascript"); + extensionToMimetypeMap.put("mocha", "application/javascript"); + extensionToMimetypeMap.put("ls", "application/javascript"); extensionToMimetypeMap.put("latex", "application/x-latex"); extensionToMimetypeMap.put("torrent", "application/x-bittorrent"); extensionToMimetypeMap.put("vpg", "application/x-vpeg005"); @@ -129,7 +129,6 @@ private static void addApplicationXMimetypeOne(Map extensionToMi extensionToMimetypeMap.put("906", "application/x-906"); extensionToMimetypeMap.put("anv", "application/x-anv"); extensionToMimetypeMap.put("a11", "application/x-a11"); - extensionToMimetypeMap.put("bmp", "application/x-bmp"); extensionToMimetypeMap.put("bot", "application/x-bot"); extensionToMimetypeMap.put("bz2", "application/x-bzip2"); extensionToMimetypeMap.put("c4t", "application/x-c4t"); @@ -175,7 +174,6 @@ private static void addApplicationXMimetypeTwo(Map extensionToMi extensionToMimetypeMap.put("hpl", "application/x-hpl"); extensionToMimetypeMap.put("hrf", "application/x-hrf"); extensionToMimetypeMap.put("icb", "application/x-icb"); - extensionToMimetypeMap.put("ico", "application/x-ico"); extensionToMimetypeMap.put("iff", "application/x-iff"); extensionToMimetypeMap.put("ig4", "application/x-g4"); extensionToMimetypeMap.put("igs", "application/x-igs"); @@ -440,6 +438,8 @@ private static void addImageMimetype(Map extensionToMimetypeMap) extensionToMimetypeMap.put("xbm", "image/x-xbitmap"); extensionToMimetypeMap.put("xpm", "image/x-xpixmap"); extensionToMimetypeMap.put("webp", "image/webp"); + extensionToMimetypeMap.put("ico", "image/x-icon"); + extensionToMimetypeMap.put("bmp", "image/bmp"); } private static void addAudioMimetype(Map extensionToMimetypeMap) { diff --git a/app/src/main/java/com/obs/services/internal/utils/ServiceUtils.java b/app/src/main/java/com/obs/services/internal/utils/ServiceUtils.java index bf88f44..d4a1eb2 100644 --- a/app/src/main/java/com/obs/services/internal/utils/ServiceUtils.java +++ b/app/src/main/java/com/obs/services/internal/utils/ServiceUtils.java @@ -883,4 +883,51 @@ public static String messageMasked(String info) { } } + public static String escapeXml11(String input) { + if (input == null) { + return null; + } + + StringBuilder result = new StringBuilder(input.length() + 16); + + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + + switch (c) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + case '"': + result.append("""); + break; + case '\'': + result.append("'"); + break; + default: + if (isValidXml11Char(c)) { + result.append(c); + } else { + result.append("&#x").append(Integer.toHexString(c).toUpperCase(Locale.ROOT)).append(";"); + } + break; + } + } + + return result.toString(); + } + + private static boolean isValidXml11Char(char c) { + if (c >= 0x20 && c <= 0xD7FF) return true; + if (c >= 0xE000 && c <= 0xFFFD) return true; + if (c == 0x09 || c == 0x0A || c == 0x0D) return true; + + return false; + } + } diff --git a/app/src/main/java/com/obs/services/internal/xml/QosConfigurationXMLBuilder.java b/app/src/main/java/com/obs/services/internal/xml/QosConfigurationXMLBuilder.java new file mode 100644 index 0000000..211ead8 --- /dev/null +++ b/app/src/main/java/com/obs/services/internal/xml/QosConfigurationXMLBuilder.java @@ -0,0 +1,101 @@ +package com.obs.services.internal.xml; + +import com.obs.log.ILogger; +import com.obs.log.LoggerBuilder; +import com.obs.services.exception.ObsException; +import com.obs.services.model.Qos.QosConfiguration; + +import java.util.Optional; + +public class QosConfigurationXMLBuilder extends ObsSimpleXMLBuilder { + private static final ILogger log = LoggerBuilder.getLogger("com.obs.services.ObsClient"); + + public String buildXML(QosConfiguration qosConfiguration) throws ObsException { + checkQosConfiguration(qosConfiguration); + startElement("PutBucketQoSRequestBody"); + startElement("QoSConfiguration"); + qosConfiguration.getRules().forEach(rule -> { + startElement("QoSRule"); + Optional.ofNullable(rule.getNetworkType()) + .ifPresent(nt -> { + startElement("NetworkType"); + append(nt.getCode()); + endElement("NetworkType"); + }); + Optional.of(rule.getConcurrentRequestLimit()) + .ifPresent(crl -> { + startElement("ConcurrentRequestLimit"); + append(String.valueOf(crl)); + endElement("ConcurrentRequestLimit"); + }); + Optional.ofNullable(rule.getQpsLimit()) + .ifPresent(qpsLimit -> { + startElement("QpsLimit"); + Optional.of(qpsLimit.getQpsGetLimit()) + .ifPresent(getQps -> { + startElement("Get"); + append(String.valueOf(getQps)); + endElement("Get"); + }); + Optional.of(qpsLimit.getQpsPutPostDeleteLimit()) + .ifPresent(putPostDeleteQps -> { + startElement("PutPostDelete"); + append(String.valueOf(putPostDeleteQps)); + endElement("PutPostDelete"); + }); + Optional.of(qpsLimit.getQpsListLimit()) + .ifPresent(listQps -> { + startElement("List"); + append(String.valueOf(listQps)); + endElement("List"); + }); + Optional.of(qpsLimit.getQpsTotalLimit()) + .ifPresent(totalQps -> { + startElement("Total"); + append(String.valueOf(totalQps)); + endElement("Total"); + }); + endElement("QpsLimit"); + }); + Optional.ofNullable(rule.getBpsLimit()) + .ifPresent(bpsLimit -> { + startElement("BpsLimit"); + Optional.of(bpsLimit.getBpsGetLimit()) + .ifPresent(getBps -> { + startElement("Get"); + append(String.valueOf(getBps)); + endElement("Get"); + }); + Optional.of(bpsLimit.getBpsPutPostLimit()) + .ifPresent(putPostBps -> { + startElement("PutPost"); + append(String.valueOf(putPostBps)); + endElement("PutPost"); + }); + Optional.of(bpsLimit.getBpsTotalLimit()) + .ifPresent(totalBps -> { + startElement("Total"); + append(String.valueOf(totalBps)); + endElement("Total"); + }); + endElement("BpsLimit"); + }); + endElement("QoSRule"); + }); + endElement("QoSConfiguration"); + endElement("PutBucketQoSRequestBody"); + return getXmlBuilder().toString(); + } + + protected void checkQosConfiguration(QosConfiguration qosConfiguration) { + if (qosConfiguration == null) { + String errorMessage = "qosConfiguration is null, failed to build request XML!"; + log.error(errorMessage); + throw new ObsException(errorMessage); + } else if (qosConfiguration.getRules() == null || qosConfiguration.getRules().isEmpty()) { + String errorMessage = "qosConfiguration's QosRuleList is null or empty, failed to build request XML!"; + log.error(errorMessage); + throw new ObsException(errorMessage); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/BaseSnapshotRequest.java b/app/src/main/java/com/obs/services/model/BaseSnapshotRequest.java new file mode 100644 index 0000000..8f7ae63 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/BaseSnapshotRequest.java @@ -0,0 +1,23 @@ +package com.obs.services.model; + +public abstract class BaseSnapshotRequest extends BaseObjectRequest { + + protected String snapshotName; + + protected BaseSnapshotRequest(String bucketName, String objectKey, String snapshotName) { + this.bucketName = bucketName; + this.objectKey = objectKey; + this.snapshotName = snapshotName; + + } + + public String getSnapshotName() { + return snapshotName; + } + + protected void validateSnapshotName() { + if (snapshotName == null || snapshotName.trim().isEmpty()) { + throw new IllegalArgumentException("Snapshot name cannot be null or empty"); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/CreateSnapshotRequest.java b/app/src/main/java/com/obs/services/model/CreateSnapshotRequest.java new file mode 100644 index 0000000..7aabc91 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/CreateSnapshotRequest.java @@ -0,0 +1,20 @@ +package com.obs.services.model; + +public class CreateSnapshotRequest extends BaseSnapshotRequest { + + { + httpMethod = HttpMethodEnum.POST; + } + + public CreateSnapshotRequest(String bucketName, String objectKey, String snapshotName) { + super(bucketName, objectKey, snapshotName); + validateSnapshotName(); + } + + + @Override + public String toString() { + return "CreateSnapshotRequest [bucketName=" + bucketName + + ", objectKey=" + objectKey + ", snapshotName=" + snapshotName + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/CreateSnapshotResponse.java b/app/src/main/java/com/obs/services/model/CreateSnapshotResponse.java new file mode 100644 index 0000000..e362f49 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/CreateSnapshotResponse.java @@ -0,0 +1,16 @@ +package com.obs.services.model; + +/** + * Response for creating snapshot + * Since this only returns Status, Request ID, and Err, we extend HeaderResponse + */ +public class CreateSnapshotResponse extends HeaderResponse { + + public CreateSnapshotResponse() { + } + + @Override + public String toString() { + return "CreateSnapshotResponse [statusCode=" + getStatusCode() + ", requestId=" + getRequestId() + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/DeleteBucketLifecycleRequest.java b/app/src/main/java/com/obs/services/model/DeleteBucketLifecycleRequest.java new file mode 100644 index 0000000..2d438da --- /dev/null +++ b/app/src/main/java/com/obs/services/model/DeleteBucketLifecycleRequest.java @@ -0,0 +1,46 @@ +/** + * Copyright 2019 Huawei Technologies Co.,Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.obs.services.model; + +/** + * + * + * @since 3.25.10 + */ +public class DeleteBucketLifecycleRequest extends BaseBucketRequest { + + { + httpMethod = HttpMethodEnum.DELETE; + } + + private String ruleId; + + public DeleteBucketLifecycleRequest(String bucketName) { + this.bucketName = bucketName; + } + + public DeleteBucketLifecycleRequest(String bucketName, String ruleId) { + this.bucketName = bucketName; + this.ruleId = ruleId; + } + + public String getRuleId() { + return ruleId; + } + + public void setRuleId(String ruleId) { + this.ruleId = ruleId; + } +} diff --git a/app/src/main/java/com/obs/services/model/DeleteSnapshotRequest.java b/app/src/main/java/com/obs/services/model/DeleteSnapshotRequest.java new file mode 100644 index 0000000..afedc80 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/DeleteSnapshotRequest.java @@ -0,0 +1,14 @@ +package com.obs.services.model; + +public class DeleteSnapshotRequest extends BaseSnapshotRequest { + + { + httpMethod = HttpMethodEnum.DELETE; + } + + public DeleteSnapshotRequest(String bucketName, String objectKey, String snapshotName) { + super(bucketName, objectKey, snapshotName); + validateSnapshotName(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/GetBucketLifecycleRequest.java b/app/src/main/java/com/obs/services/model/GetBucketLifecycleRequest.java new file mode 100644 index 0000000..4afa567 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/GetBucketLifecycleRequest.java @@ -0,0 +1,60 @@ +/** + * Copyright 2019 Huawei Technologies Co.,Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.obs.services.model; + +/** + * + * + * @since 3.25.10 + */ +public class GetBucketLifecycleRequest extends BaseBucketRequest { + + { + httpMethod = HttpMethodEnum.GET; + } + + private String ruleId; + private String ruleIdMarker; + + public GetBucketLifecycleRequest(String bucketName) { + this.bucketName = bucketName; + } + + public GetBucketLifecycleRequest(String bucketName, String ruleId) { + this(bucketName); + this.ruleId = ruleId; + } + + public GetBucketLifecycleRequest(String bucketName, String ruleId, String ruleIdMarker) { + this(bucketName, ruleId); + this.ruleIdMarker = ruleIdMarker; + } + + public String getRuleId() { + return ruleId; + } + + public String getRuleIdMarker() { + return ruleIdMarker; + } + + public void setRuleId(String ruleId) { + this.ruleId = ruleId; + } + + public void setRuleIdMarker(String ruleIdMarker) { + this.ruleIdMarker = ruleIdMarker; + } +} diff --git a/app/src/main/java/com/obs/services/model/GetSnapshotListRequest.java b/app/src/main/java/com/obs/services/model/GetSnapshotListRequest.java new file mode 100644 index 0000000..f48298b --- /dev/null +++ b/app/src/main/java/com/obs/services/model/GetSnapshotListRequest.java @@ -0,0 +1,139 @@ +package com.obs.services.model; + +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_MAX_KEYS; + +/** + * Request for getting snapshot list + */ +public class GetSnapshotListRequest extends BaseObjectRequest { + + { + httpMethod = HttpMethodEnum.GET; + } + + private String marker; + private int maxKeys; + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + */ + public GetSnapshotListRequest(String bucketName, String objectKey) { + this(bucketName, objectKey, null, SNAPSHOT_MAX_KEYS); + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + * @param marker + * Start position for listing snapshots + */ + public GetSnapshotListRequest(String bucketName, String objectKey, String marker) { + this(bucketName, objectKey, marker, SNAPSHOT_MAX_KEYS); + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + * @param maxKeys + * Maximum number of snapshots to be returned + */ + public GetSnapshotListRequest(String bucketName, String objectKey, int maxKeys) { + this(bucketName, objectKey, null, maxKeys); + } + + /** + * Main constructor - all field assignments happen here only + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + * @param marker + * Start position for listing snapshots + * @param maxKeys + * Maximum number of snapshots to be returned + */ + public GetSnapshotListRequest(String bucketName, String objectKey, String marker, int maxKeys) { + // All field assignments consolidated in main constructor + this.bucketName = bucketName; + this.objectKey = objectKey; + this.marker = marker; + this.maxKeys = maxKeys; + } + + /** + * Obtain the object key. + * + * @return Object key + */ + public String getObjectKey() { + return objectKey; + } + + /** + * Set the object key. + * + * @param objectKey + * Object key + */ + public void setObjectKey(String objectKey) { + this.objectKey = objectKey; + } + + /** + * Obtain the start position for listing snapshots. + * + * @return Start position marker + */ + public String getMarker() { + return marker; + } + + /** + * Set the start position for listing snapshots. + * + * @param marker + * Start position marker + */ + public void setMarker(String marker) { + this.marker = marker; + } + + /** + * Obtain the maximum number of snapshots to be returned. + * + * @return Maximum number of snapshots + */ + public int getMaxKeys() { + return maxKeys; + } + + /** + * Set the maximum number of snapshots to be returned. + * + * @param maxKeys + * Maximum number of snapshots + */ + public void setMaxKeys(int maxKeys) { + this.maxKeys = maxKeys; + } + + @Override + public String toString() { + return "GetSnapshotListRequest [bucketName=" + bucketName + ", objectKey=" + objectKey + + ", marker=" + marker + ", maxKeys=" + maxKeys + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/GetSnapshotListResponse.java b/app/src/main/java/com/obs/services/model/GetSnapshotListResponse.java new file mode 100644 index 0000000..b79160e --- /dev/null +++ b/app/src/main/java/com/obs/services/model/GetSnapshotListResponse.java @@ -0,0 +1,149 @@ +package com.obs.services.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +/** + * Response for getting snapshot list + */ +public class GetSnapshotListResponse extends HeaderResponse { + + private String marker; + private String nextMarker; + private boolean truncated; + private int maxKeys; + private int snapshotCount; + private List snapshotList; + + public GetSnapshotListResponse(String marker, String nextMarker, boolean truncated, int maxKeys, int snapshotCount, List snapshots) { + this.marker = marker; + this.nextMarker = nextMarker; + this.truncated = truncated; + this.maxKeys = maxKeys; + this.snapshotCount = snapshotCount; + this.snapshotList = snapshots != null ? new ArrayList<>(snapshots) : new ArrayList<>(); + + } + + /** + * Obtain the marker for the current listing position. + * + * @return Current marker + */ + public String getMarker() { + return marker; + } + + /** + * Set the marker for the current listing position. + * + * @param marker + * Current marker + */ + public void setMarker(String marker) { + this.marker = marker; + } + + /** + * Obtain the next marker for pagination. + * + * @return Next marker + */ + public String getNextMarker() { + return nextMarker; + } + + /** + * Set the next marker for pagination. + * + * @param nextMarker + * Next marker + */ + public void setNextMarker(String nextMarker) { + this.nextMarker = nextMarker; + } + + /** + * Check if the result is truncated. + * + * @return true if truncated, false otherwise + */ + public boolean isTruncated() { + return truncated; + } + + /** + * Set whether the result is truncated. + * + * @param truncated + * Truncation status + */ + public void setTruncated(boolean truncated) { + this.truncated = truncated; + } + + /** + * Obtain the maximum number of snapshots requested. + * + * @return Maximum number of snapshots + */ + public int getMaxKeys() { + return maxKeys; + } + + /** + * Set the maximum number of snapshots requested. + * + * @param maxKeys + * Maximum number of snapshots + */ + public void setMaxKeys(int maxKeys) { + this.maxKeys = maxKeys; + } + + /** + * Obtain the number of snapshots returned. + * + * @return Snapshot count + */ + public int getSnapshotCount() { + return snapshotCount; + } + + /** + * Set the number of snapshots returned. + * + * @param snapshotCount + * Snapshot count + */ + public void setSnapshotCount(int snapshotCount) { + this.snapshotCount = snapshotCount; + } + + /** + * Obtain the list of snapshots. + * + * @return Snapshot list + */ + public List getSnapshotList() { + return Collections.unmodifiableList(snapshotList); + } + + /** + * Set the list of snapshots. + * + * @param snapshotList + * Snapshot list + */ + public void setSnapshotList(List snapshotList) { + this.snapshotList = snapshotList != null ? new ArrayList<>(snapshotList) : new ArrayList<>(); + } + + @Override + public String toString() { + return "GetSnapshotListResponse [marker=" + marker + ", nextMarker=" + nextMarker + + ", truncated=" + truncated + ", maxKeys=" + maxKeys + ", snapshotCount=" + snapshotCount + + ", snapshotList=" + snapshotList + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/GetSnapshottableDirListRequest.java b/app/src/main/java/com/obs/services/model/GetSnapshottableDirListRequest.java new file mode 100644 index 0000000..99f0679 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/GetSnapshottableDirListRequest.java @@ -0,0 +1,106 @@ +/** + * Copyright 2019 Huawei Technologies Co.,Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.obs.services.model; + +import static com.obs.services.internal.ObsConstraint.SNAPSHOT_MAX_KEYS; + +/** + * Request parameters for getting a list of directories under a bucket that have been set to allow snapshots. + * + * @since 3.20.3 + */ +public class GetSnapshottableDirListRequest extends GenericRequest { + { + httpMethod = HttpMethodEnum.GET; + } + + private String marker; + + private int maxKeys; + + /** + * Constructor + * + * @param bucketName + * Bucket name + */ + public GetSnapshottableDirListRequest(String bucketName) { + this(bucketName, null, SNAPSHOT_MAX_KEYS); + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param marker + * Marker + */ + public GetSnapshottableDirListRequest(String bucketName, String marker) { + this(bucketName, marker, SNAPSHOT_MAX_KEYS); + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param maxKeys + * maxKeys + */ + public GetSnapshottableDirListRequest(String bucketName, int maxKeys) { + this(bucketName, null, maxKeys); + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param marker + * Marker + * @param maxKeys + * Max keys + */ + public GetSnapshottableDirListRequest(String bucketName, String marker, int maxKeys) { + this.bucketName = bucketName; + this.marker = marker; + this.maxKeys = maxKeys; + } + + /** + * Obtain the marker that will be used as an identifier as the starting position for listing. + * + * @return Marker + */ + public String getMarker() { + return marker; + } + + /** + * Obtain the maximum number of snapshot directories to list. + * + * @return Max Keys + */ + public int getMaxKeys() { + return maxKeys; + } + + @Override + public String toString() { + return "GetSnapshottableDirListRequest [bucketName=" + bucketName + + ", marker=" + marker + ", maxKeys=" + maxKeys + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/GetSnapshottableDirListResult.java b/app/src/main/java/com/obs/services/model/GetSnapshottableDirListResult.java new file mode 100644 index 0000000..92fe99c --- /dev/null +++ b/app/src/main/java/com/obs/services/model/GetSnapshottableDirListResult.java @@ -0,0 +1,52 @@ +package com.obs.services.model; + +import java.util.List; + +public class GetSnapshottableDirListResult extends HeaderResponse{ + private String marker; + + private String nextMarker; + + private boolean truncated; + + private int maxKeys; + + private int snapshottableDirCount; + + private List snapshottableDir; + + public GetSnapshottableDirListResult(String marker, String nextMarker, boolean truncated, int maxKeys, + int snapshottableDirCount, List snapshottableDir) { + this.marker = marker; + this.nextMarker = nextMarker; + this.truncated = truncated; + this.maxKeys = maxKeys; + this.snapshottableDirCount = snapshottableDirCount; + this.snapshottableDir = snapshottableDir; + } + + public GetSnapshottableDirListResult(String marker, String nextMarker, boolean truncated, int maxKeys) { + this.marker = marker; + this.nextMarker = nextMarker; + this.truncated = truncated; + this.maxKeys = maxKeys; + this.snapshottableDirCount = 0; + } + + public String getMarker() { + return marker; + } + + public String getNextMarker() { + return nextMarker; + } + + public boolean isTruncated() { return truncated; } + + public int getMaxKeys() { return maxKeys; } + + public int getSnapshottableDirCount() { return snapshottableDirCount; } + + public List getSnapshottableDir() { return snapshottableDir; } + +} diff --git a/app/src/main/java/com/obs/services/model/LifecycleConfiguration.java b/app/src/main/java/com/obs/services/model/LifecycleConfiguration.java index 1915844..de25889 100644 --- a/app/src/main/java/com/obs/services/model/LifecycleConfiguration.java +++ b/app/src/main/java/com/obs/services/model/LifecycleConfiguration.java @@ -892,7 +892,7 @@ public void setNoncurrentVersionTransitions(List no public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + getOuterType().hashCode(); + result = prime * result + getOuterType().getClass().hashCode(); result = prime * result + ((enabled == null) ? 0 : enabled.hashCode()); result = prime * result + ((expiration == null) ? 0 : expiration.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); @@ -915,7 +915,7 @@ public boolean equals(Object obj) { } Rule other = (Rule) obj; - if (!getOuterType().equals(other.getOuterType())) { + if (!getOuterType().getClass().equals(other.getOuterType().getClass())) { return false; } diff --git a/app/src/main/java/com/obs/services/model/ListVersionsResult.java b/app/src/main/java/com/obs/services/model/ListVersionsResult.java index c54c082..cd964b7 100644 --- a/app/src/main/java/com/obs/services/model/ListVersionsResult.java +++ b/app/src/main/java/com/obs/services/model/ListVersionsResult.java @@ -46,11 +46,13 @@ public class ListVersionsResult extends HeaderResponse { private String delimiter; + private String snapshotId; + @Deprecated //CHECKSTYLE:OFF public ListVersionsResult(String bucketName, String prefix, String keyMarker, String nextKeyMarker, String versionIdMarker, String nextVersionIdMarker, String maxKeys, boolean isTruncated, - VersionOrDeleteMarker[] versions, List commonPrefixes, String location, String delimiter) { + VersionOrDeleteMarker[] versions, List commonPrefixes, String location, String delimiter, String snapshotId) { super(); this.bucketName = bucketName; this.prefix = prefix; @@ -68,6 +70,7 @@ public ListVersionsResult(String bucketName, String prefix, String keyMarker, St this.commonPrefixes = commonPrefixes; this.location = location; this.delimiter = delimiter; + this.snapshotId = snapshotId; } private ListVersionsResult(Builder builder) { @@ -88,6 +91,7 @@ private ListVersionsResult(Builder builder) { this.commonPrefixes = builder.commonPrefixes; this.location = builder.location; this.delimiter = builder.delimiter; + this.snapshotId = builder.snapshotId; } public static final class Builder { @@ -103,6 +107,7 @@ public static final class Builder { private List commonPrefixes; private String location; private String delimiter; + private String snapshotId; public Builder bucketName(String bucketName) { this.bucketName = bucketName; @@ -167,6 +172,11 @@ public Builder delimiter(String delimiter) { this.delimiter = delimiter; return this; } + + public Builder snapshotId(String snapshotId) { + this.snapshotId = snapshotId; + return this; + } public ListVersionsResult builder() { return new ListVersionsResult(this); @@ -292,13 +302,22 @@ public String getDelimiter() { return delimiter; } + /** + * Obtain the snapshot ID. + * + * @return Snapshot ID + */ + public String getSnapshotId() { + return snapshotId; + } + @Override public String toString() { return "ListVersionsResult [bucketName=" + bucketName + ", prefix=" + prefix + ", keyMarker=" + keyMarker + ", nextKeyMarker=" + nextKeyMarker + ", versionIdMarker=" + versionIdMarker + ", nextVersionIdMarker=" + nextVersionIdMarker + ", maxKeys=" + maxKeys + ", isTruncated=" + isTruncated + ", versions=" + Arrays.toString(versions) + ", commonPrefixes=" + commonPrefixes + ", location=" + location - + ", delimiter=" + delimiter + "]"; + + ", delimiter=" + delimiter + ", snapshotId=" + snapshotId + "]"; } } diff --git a/app/src/main/java/com/obs/services/model/Qos/BpsLimitConfiguration.java b/app/src/main/java/com/obs/services/model/Qos/BpsLimitConfiguration.java new file mode 100644 index 0000000..ff2dd2a --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/BpsLimitConfiguration.java @@ -0,0 +1,53 @@ +package com.obs.services.model.Qos; + +public class BpsLimitConfiguration { + private long get; + private long putPost; + private long total; + + // 构造方法 + public BpsLimitConfiguration(long getValue, long putPostValue, long totalValue) { + validateNonNegative(getValue, "get"); + validateNonNegative(putPostValue, "putPost"); + validateNonNegative(totalValue, "total"); + + this.get = getValue; + this.putPost = putPostValue; + this.total = totalValue; + } + + private static void validateNonNegative(long value, String name) { + if (value < 0) { + throw new IllegalArgumentException(name + " value cannot be negative: " + value); + } + } + + // Getter 和 Setter 方法 + + public long getBpsGetLimit() { + return get; + } + + public void setBpsGetLimit(long getValue) { + validateNonNegative(getValue, "get"); + this.get = getValue; + } + + public long getBpsPutPostLimit() { + return putPost; + } + + public void setBpsPutPostLimit(long putPostValue) { + validateNonNegative(putPostValue, "putPost"); + this.putPost = putPostValue; + } + + public long getBpsTotalLimit() { + return total; + } + + public void setBpsTotalLimit(long totalValue) { + validateNonNegative(totalValue, "total"); + this.total = totalValue; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/Qos/DeleteBucketQosRequest.java b/app/src/main/java/com/obs/services/model/Qos/DeleteBucketQosRequest.java new file mode 100644 index 0000000..a4677b0 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/DeleteBucketQosRequest.java @@ -0,0 +1,16 @@ +package com.obs.services.model.Qos; + +import com.obs.services.model.BaseBucketRequest; +import com.obs.services.model.HttpMethodEnum; + +public class DeleteBucketQosRequest extends BaseBucketRequest { + { + httpMethod = HttpMethodEnum.DELETE; + } + + public DeleteBucketQosRequest(String bucketName){ + super(bucketName); + } +} + + diff --git a/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSRequest.java b/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSRequest.java new file mode 100644 index 0000000..9874b35 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSRequest.java @@ -0,0 +1,14 @@ +package com.obs.services.model.Qos; + +import com.obs.services.model.BaseBucketRequest; +import com.obs.services.model.HttpMethodEnum; + +public class GetBucketQoSRequest extends BaseBucketRequest { + { + httpMethod = HttpMethodEnum.GET; + } + + public GetBucketQoSRequest(String bucketName){ + super(bucketName); + } +} diff --git a/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSResult.java b/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSResult.java new file mode 100644 index 0000000..9acc88f --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/GetBucketQoSResult.java @@ -0,0 +1,65 @@ +package com.obs.services.model.Qos; + +import com.obs.services.model.HeaderResponse; + +import java.util.ArrayList; +import java.util.List; + +public class GetBucketQoSResult extends HeaderResponse { + private String qosGroup = ""; + private List bucketQosRules = new ArrayList<>(); + private List groupQosRules = new ArrayList<>(); + + /** + * 获取Bucket的QoS规则列表 + */ + public List getBucketQosRules() { + return bucketQosRules; + } + + /** + * 设置Bucket的QoS规则列表 + */ + public void setBucketQosRules(List bucketQosRules) { + this.bucketQosRules = bucketQosRules; + } + + /** + * 获取QoS组的QoS规则列表 + */ + public List getGroupQosRules() { + return groupQosRules; + } + + /** + * 设置QoS组的QoS规则列表 + */ + public void setGroupQosRules(List groupQosRules) { + this.groupQosRules = groupQosRules; + } + + /** + * 获取QoS组名称 + */ + public String getQosGroup() { + return qosGroup; + } + + /** + * 设置QoS组名称 + */ + public void setQosGroup(String qosGroup) { + this.qosGroup = qosGroup; + } + + @Override + public String toString() { + return "GetBucketQoSResult{" + + "statusCode=" + getStatusCode() + + ", requestId='" + getRequestId() + '\'' + + ", qosGroup='" + qosGroup + '\'' + + ", bucketQosRules=" + bucketQosRules + + ", groupQosRules=" + groupQosRules + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/Qos/NetworkType.java b/app/src/main/java/com/obs/services/model/Qos/NetworkType.java new file mode 100644 index 0000000..9602d9f --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/NetworkType.java @@ -0,0 +1,34 @@ +package com.obs.services.model.Qos; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public enum NetworkType { + INTRANET("intranet"), + EXTRANET("extranet"), + TOTAL("total"); + private String code; + private static Map mp = new HashMap<>(); + + static { + for (NetworkType type : NetworkType.values()) { + mp.put(type.code.toLowerCase(Locale.ENGLISH), type); + } + } + + NetworkType(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public static NetworkType getValueFromCode(String code) { + if (code == null || code.isEmpty()) { + return null; + } + return mp.get(code.toLowerCase(Locale.ENGLISH)); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/Qos/QosConfiguration.java b/app/src/main/java/com/obs/services/model/Qos/QosConfiguration.java new file mode 100644 index 0000000..5abac49 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/QosConfiguration.java @@ -0,0 +1,42 @@ +package com.obs.services.model.Qos; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class QosConfiguration { + private List rules; + + public QosConfiguration(){ + + } + + public QosConfiguration(QosRule rule1, QosRule rule2) { + // 传递两个参数 分别设置内网 和 外网的qos + this.rules = new ArrayList<>(); + this.rules.add(rule1); + if (rule2 != null) { + this.rules.add(rule2); + } + this.rules = Collections.unmodifiableList(this.rules); + } + + public QosConfiguration(QosRule rule) { + // 传递一个参数直接设置total的qos + this.rules = new ArrayList<>(); + this.rules.add(rule); + this.rules = Collections.unmodifiableList(this.rules); + } + + public List getRules() { + return rules; + } + + public void setRules(List rules){ + if (rules == null){ + this.rules = null; + }else{ + this.rules = Collections.unmodifiableList(new ArrayList<>(rules)); + } + } +} diff --git a/app/src/main/java/com/obs/services/model/Qos/QosRule.java b/app/src/main/java/com/obs/services/model/Qos/QosRule.java new file mode 100644 index 0000000..be46354 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/QosRule.java @@ -0,0 +1,56 @@ +package com.obs.services.model.Qos; + +public class QosRule { + private NetworkType networkType; + private long concurrentRequestLimit; + private QpsLimitConfiguration qpsLimit; + private BpsLimitConfiguration bpsLimit; + private static void validateNonNegative(long value, String name) { + if (value < 0) { + throw new IllegalArgumentException(name + " value cannot be negative: " + value); + } + } + + + public QosRule(NetworkType networkType, long concurrentRequestLimitValue, QpsLimitConfiguration qpsLimit, BpsLimitConfiguration bpsLimit) { + validateNonNegative(concurrentRequestLimitValue, "concurrentRequestLimit"); + + this.networkType = networkType; + this.concurrentRequestLimit = concurrentRequestLimitValue; + this.qpsLimit = qpsLimit; + this.bpsLimit = bpsLimit; + } + + public NetworkType getNetworkType() { + return networkType; + } + + public void setNetworkType(NetworkType networkType) { + this.networkType = networkType; + } + + public long getConcurrentRequestLimit() { + return concurrentRequestLimit; + } + + public void setConcurrentRequestLimit(long concurrentRequestLimitValue) { + validateNonNegative(concurrentRequestLimitValue, "concurrentRequestLimit"); + this.concurrentRequestLimit = concurrentRequestLimitValue; + } + + public QpsLimitConfiguration getQpsLimit() { + return qpsLimit; + } + + public void setQpsLimit(QpsLimitConfiguration qpsLimit) { + this.qpsLimit = qpsLimit; + } + + public BpsLimitConfiguration getBpsLimit() { + return bpsLimit; + } + + public void setBpsLimit(BpsLimitConfiguration bpsLimit) { + this.bpsLimit = bpsLimit; + } +} diff --git a/app/src/main/java/com/obs/services/model/Qos/QpsLimitConfiguration.java b/app/src/main/java/com/obs/services/model/Qos/QpsLimitConfiguration.java new file mode 100644 index 0000000..9e3e0ff --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/QpsLimitConfiguration.java @@ -0,0 +1,63 @@ +package com.obs.services.model.Qos; + +public class QpsLimitConfiguration { + private long get; + private long putPostDelete; + private long list; + private long total; + + private static void validateNonNegative(long value, String name) { + if (value < 0) { + throw new IllegalArgumentException(name + " value cannot be negative: " + value); + } + } + + public QpsLimitConfiguration(long getValue, long putPostDeleteValue, long listValue, long totalValue) { + validateNonNegative(getValue, "get"); + validateNonNegative(putPostDeleteValue, "putPostDelete"); + validateNonNegative(listValue, "list"); + validateNonNegative(totalValue, "total"); + + this.get = getValue; + this.putPostDelete = putPostDeleteValue; + this.list = listValue; + this.total = totalValue; + } + + + public long getQpsGetLimit() { + return get; + } + + public void setQpsGetLimit(long getValue) { + validateNonNegative(getValue, "get"); + this.get = getValue; + } + + public long getQpsPutPostDeleteLimit() { + return putPostDelete; + } + + public void setQpsPutPostDeleteLimit(long putPostDeleteValue) { + validateNonNegative(putPostDeleteValue, "putPostDelete"); + this.putPostDelete = putPostDeleteValue; + } + + public long getQpsListLimit() { + return list; + } + + public void setQpsListLimit(long listValue) { + validateNonNegative(listValue, "list"); + this.list = listValue; + } + + public long getQpsTotalLimit() { + return total; + } + + public void setQpsTotalLimit(long totalValue) { + validateNonNegative(totalValue, "total"); + this.total = totalValue; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/Qos/SetBucketQosRequest.java b/app/src/main/java/com/obs/services/model/Qos/SetBucketQosRequest.java new file mode 100644 index 0000000..8d89f79 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Qos/SetBucketQosRequest.java @@ -0,0 +1,23 @@ +package com.obs.services.model.Qos; + +import com.obs.services.model.BaseBucketRequest; +import com.obs.services.model.HttpMethodEnum; + +public class SetBucketQosRequest extends BaseBucketRequest { + { + httpMethod = HttpMethodEnum.PUT; + } + private QosConfiguration qosConfig; + public SetBucketQosRequest(String bucketName,QosConfiguration qosConfig){ + super(bucketName); + this.qosConfig = qosConfig; + } + + public QosConfiguration getQosConfig() { + return qosConfig; + } + + public void setQosConfiguration(QosConfiguration qosConfig){ + this.qosConfig = qosConfig; + } +} diff --git a/app/src/main/java/com/obs/services/model/RenameSnapshotRequest.java b/app/src/main/java/com/obs/services/model/RenameSnapshotRequest.java new file mode 100644 index 0000000..a94ca89 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/RenameSnapshotRequest.java @@ -0,0 +1,96 @@ +package com.obs.services.model; + +/** + * Request for renaming snapshot + */ +public class RenameSnapshotRequest extends BaseObjectRequest { + + { + httpMethod = HttpMethodEnum.PUT; + } + + private String oldSnapshotName; + private String newSnapshotName; + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + * @param oldSnapshotName + * Old snapshot name + * @param newSnapshotName + * New snapshot name + */ + public RenameSnapshotRequest(String bucketName, String objectKey, String oldSnapshotName, String newSnapshotName) { + this.bucketName = bucketName; + this.objectKey = objectKey; + this.oldSnapshotName = oldSnapshotName; + this.newSnapshotName = newSnapshotName; + } + + /** + * Obtain the object key. + * + * @return Object key + */ + public String getObjectKey() { + return objectKey; + } + + /** + * Set the object key. + * + * @param objectKey + * Object key + */ + public void setObjectKey(String objectKey) { + this.objectKey = objectKey; + } + + /** + * Obtain the old snapshot name. + * + * @return Old snapshot name + */ + public String getOldSnapshotName() { + return oldSnapshotName; + } + + /** + * Set the old snapshot name. + * + * @param oldSnapshotName + * Old snapshot name + */ + public void setOldSnapshotName(String oldSnapshotName) { + this.oldSnapshotName = oldSnapshotName; + } + + /** + * Obtain the new snapshot name. + * + * @return New snapshot name + */ + public String getNewSnapshotName() { + return newSnapshotName; + } + + /** + * Set the new snapshot name. + * + * @param newSnapshotName + * New snapshot name + */ + public void setNewSnapshotName(String newSnapshotName) { + this.newSnapshotName = newSnapshotName; + } + + @Override + public String toString() { + return "RenameSnapshotRequest [bucketName=" + bucketName + ", objectKey=" + objectKey + + ", oldSnapshotName=" + oldSnapshotName + ", newSnapshotName=" + newSnapshotName + "]"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/RenameSnapshotResponse.java b/app/src/main/java/com/obs/services/model/RenameSnapshotResponse.java new file mode 100644 index 0000000..1cd9acb --- /dev/null +++ b/app/src/main/java/com/obs/services/model/RenameSnapshotResponse.java @@ -0,0 +1,16 @@ +package com.obs.services.model; + +/** + * Response for renaming snapshot + * Returns Status, RequestId, and Err (only if there is a mistake) + */ +public class RenameSnapshotResponse extends HeaderResponse { + + public RenameSnapshotResponse() { + } + + @Override + public String toString() { + return "RenameSnapshotResponse [statusCode=" + getStatusCode() + ", requestId=" + getRequestId() + "]"; + } +} diff --git a/app/src/main/java/com/obs/services/model/SetBucketLifecycleRequest.java b/app/src/main/java/com/obs/services/model/SetBucketLifecycleRequest.java index 4d93222..9d87ed7 100644 --- a/app/src/main/java/com/obs/services/model/SetBucketLifecycleRequest.java +++ b/app/src/main/java/com/obs/services/model/SetBucketLifecycleRequest.java @@ -26,20 +26,35 @@ public class SetBucketLifecycleRequest extends BaseBucketRequest { } private LifecycleConfiguration lifecycleConfig; + private String ruleId; public SetBucketLifecycleRequest(String bucketName, LifecycleConfiguration lifecycleConfig) { this.bucketName = bucketName; this.lifecycleConfig = lifecycleConfig; } + public SetBucketLifecycleRequest(String bucketName, String ruleId, LifecycleConfiguration lifecycleConfig) { + this.bucketName = bucketName; + this.ruleId = ruleId; + this.lifecycleConfig = lifecycleConfig; + } + public LifecycleConfiguration getLifecycleConfig() { return lifecycleConfig; } + public String getRuleId() { + return ruleId; + } + public void setLifecycleConfig(LifecycleConfiguration lifecycleConfig) { this.lifecycleConfig = lifecycleConfig; } + public void setRuleId(String ruleId) { + this.ruleId = ruleId; + } + @Override public String toString() { return "SetBucketLifecycleRequest [lifecycleConfig=" + lifecycleConfig + ", getBucketName()=" + getBucketName() diff --git a/app/src/main/java/com/obs/services/model/SetDisallowSnapshotRequest.java b/app/src/main/java/com/obs/services/model/SetDisallowSnapshotRequest.java new file mode 100644 index 0000000..ae234b7 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/SetDisallowSnapshotRequest.java @@ -0,0 +1,41 @@ +/** + * Copyright 2019 Huawei Technologies Co.,Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.obs.services.model; + +/** + * Request parameters for disallowing a directory to create snapshots. + * + * @since 3.20.3 + */ +public class SetDisallowSnapshotRequest extends BaseObjectRequest { + + { + httpMethod = HttpMethodEnum.DELETE; + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object name + */ + public SetDisallowSnapshotRequest(String bucketName, String objectKey) { + this.bucketName = bucketName; + this.objectKey = objectKey; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/SetSnapshotAllowRequest.java b/app/src/main/java/com/obs/services/model/SetSnapshotAllowRequest.java new file mode 100644 index 0000000..5c500cc --- /dev/null +++ b/app/src/main/java/com/obs/services/model/SetSnapshotAllowRequest.java @@ -0,0 +1,41 @@ +/** + * Copyright 2019 Huawei Technologies Co.,Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.obs.services.model; + +/** + * Request parameters for allowing a directory to create snapshots + * + * @since 3.20.3 + */ +public class SetSnapshotAllowRequest extends BaseObjectRequest { + + { + httpMethod = HttpMethodEnum.POST; + } + + /** + * Constructor + * + * @param bucketName + * Bucket name + * @param objectKey + * Object key + */ + public SetSnapshotAllowRequest(String bucketName, String objectKey) { + this.bucketName = bucketName; + this.objectKey = objectKey; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/Snapshot.java b/app/src/main/java/com/obs/services/model/Snapshot.java new file mode 100644 index 0000000..7559b22 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/Snapshot.java @@ -0,0 +1,103 @@ +package com.obs.services.model; + +import java.util.Date; +import java.util.Objects; + +/** + * Represents a snapshot + */ +public class Snapshot { + + private String snapshotName; + private Date modifyTime; + private String snapshotID; + + public Snapshot() { + } + + public Snapshot(String snapshotName, Date modifyTime, String snapshotID) { + this.snapshotName = snapshotName; + this.modifyTime = modifyTime; + this.snapshotID = snapshotID; + } + + /** + * Obtain the snapshot name. + * + * @return Snapshot name + */ + public String getSnapshotName() { + return snapshotName; + } + + /** + * Set the snapshot name. + * + * @param snapshotName + * Snapshot name + */ + public void setSnapshotName(String snapshotName) { + this.snapshotName = snapshotName; + } + + /** + * Obtain the modify time. + * + * @return Modify time + */ + public Date getModifyTime() { + return modifyTime; + } + + /** + * Set the modify time. + * + * @param modifyTime + * Modify time + */ + public void setModifyTime(Date modifyTime) { + this.modifyTime = modifyTime; + } + + /** + * Obtain the snapshot ID. + * + * @return Snapshot ID + */ + public String getSnapshotID() { + return snapshotID; + } + + /** + * Set the snapshot ID. + * + * @param snapshotID + * Snapshot ID + */ + public void setSnapshotID(String snapshotID) { + this.snapshotID = snapshotID; + } + + @Override + public String toString() { + return "Snapshot [snapshotName=" + snapshotName + ", modifyTime=" + modifyTime + + ", snapshotID=" + snapshotID + "]"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + Snapshot snapshot = (Snapshot) obj; + return Objects.equals(snapshotID, snapshot.snapshotID); + } + + @Override + public int hashCode() { + int result = snapshotName != null ? snapshotName.hashCode() : 0; + result = 31 * result + (modifyTime != null ? modifyTime.hashCode() : 0); + result = 31 * result + (snapshotID != null ? snapshotID.hashCode() : 0); + return result; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/obs/services/model/SnapshottableDir.java b/app/src/main/java/com/obs/services/model/SnapshottableDir.java new file mode 100644 index 0000000..00c7322 --- /dev/null +++ b/app/src/main/java/com/obs/services/model/SnapshottableDir.java @@ -0,0 +1,43 @@ +package com.obs.services.model; + +import com.obs.services.internal.utils.ServiceUtils; + +import java.util.Date; + +public class SnapshottableDir { + private Date modificationTime; + + private Owner owner; + + private String group; + + private String fileId; + + private String permission; + + private Integer snapshotQuota; + + private String parentFullPath; + + public void setModificationTime(Date modificationTime) { this.modificationTime = ServiceUtils.cloneDateIgnoreNull(modificationTime); } + public Date getModificationTime() { return modificationTime; } + + public void setOwner(Owner owner) { this.owner = owner; } + public Owner getOwner() { return owner; } + + public void setGroup(String group) { this.group = group; } + public String getGroup() { return group; } + + public void setFileId(String fileId) { this.fileId = fileId; } + public String getFileId() { return fileId; } + + public void setPermission(String permission) { this.permission = permission; } + public String getPermission() { return permission; } + + public void setSnapshotQuota(Integer snapshotQuota) { this.snapshotQuota = snapshotQuota; } + public Integer getSnapshotQuota() { return snapshotQuota; } + + public void setParentFullPath(String parentFullPath) { this.parentFullPath = parentFullPath; } + public String getParentFullPath() { return parentFullPath; } + +} diff --git a/app/src/main/java/com/obs/services/model/SpecialParamEnum.java b/app/src/main/java/com/obs/services/model/SpecialParamEnum.java index 7f1e80a..1f6139b 100644 --- a/app/src/main/java/com/obs/services/model/SpecialParamEnum.java +++ b/app/src/main/java/com/obs/services/model/SpecialParamEnum.java @@ -190,6 +190,10 @@ public enum SpecialParamEnum { OBS_TRASH("x-obs-trash"), + OBS_SNAPSHOT("x-obs-snapshot"), + + OBS_SNAPSHOT_ROOT("x-obs-snapshotroot"), + INVENTORY("inventory"), PUBLIC_ACCESS_BLOCK("publicAccessBlock"), @@ -198,7 +202,9 @@ public enum SpecialParamEnum { BUCKET_PUBLIC_STATUS("bucketStatus"), - SYM_LINK("symlink"); + SYM_LINK("symlink"), + + BUCKET_QOS("x-obs-qosInfo"); /** * Specify the corresponding code in the database and the external code. diff --git a/app/src/main/java/com/obs/services/model/symlink/GetSymlinkRequest.java b/app/src/main/java/com/obs/services/model/symlink/GetSymlinkRequest.java index 27c3a8d..df77f22 100644 --- a/app/src/main/java/com/obs/services/model/symlink/GetSymlinkRequest.java +++ b/app/src/main/java/com/obs/services/model/symlink/GetSymlinkRequest.java @@ -19,6 +19,10 @@ public GetSymlinkRequest(String bucketName, String objectKey, String versionId) this.versionId = versionId; } + public GetSymlinkRequest(String bucketName, String objectKey){ + super(bucketName, objectKey); + } + public String getVersionId() { return versionId; } diff --git a/app/src/main/java/com/obs/services/model/symlink/PutSymlinkRequest.java b/app/src/main/java/com/obs/services/model/symlink/PutSymlinkRequest.java index c73b8d7..bf79504 100644 --- a/app/src/main/java/com/obs/services/model/symlink/PutSymlinkRequest.java +++ b/app/src/main/java/com/obs/services/model/symlink/PutSymlinkRequest.java @@ -25,6 +25,11 @@ public PutSymlinkRequest(String bucketName, String objectKey, String symlinkTarg this.objectMetadata = objectMetadata; } + public PutSymlinkRequest(String bucketName, String objectKey, String symlinkTarget){ + super(bucketName,objectKey); + this.symlinkTarget = symlinkTarget; + } + public String getSymlinkTarget() { return symlinkTarget; } diff --git a/pom-android.xml b/pom-android.xml index 1246bef..7c080e1 100644 --- a/pom-android.xml +++ b/pom-android.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-android - 3.25.7 + 3.25.10 jar OBS SDK for Android diff --git a/pom-dependencies.xml b/pom-dependencies.xml index c07dd12..8e00ac1 100644 --- a/pom-dependencies.xml +++ b/pom-dependencies.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java - 3.25.7 + 3.25.10 jar OBS SDK for Java diff --git a/pom-java-optimization.xml b/pom-java-optimization.xml index bdf788d..826755b 100644 --- a/pom-java-optimization.xml +++ b/pom-java-optimization.xml @@ -4,7 +4,7 @@ com.huawei.storage esdk-obs-java - 3.25.7 + 3.25.10.1 jar OBS SDK for Java diff --git a/pom-java.xml b/pom-java.xml index 845c8d8..d9bac27 100644 --- a/pom-java.xml +++ b/pom-java.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java - 3.25.7 + 3.25.10 jar OBS SDK for Java diff --git a/pom.xml b/pom.xml index de78c64..e743997 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java - 3.25.7 + 3.25.10 jar OBS SDK for Java