HDDS-13919. S3 Conditional Writes (PutObject) [1/2]#9815
HDDS-13919. S3 Conditional Writes (PutObject) [1/2]#9815jojochuang merged 39 commits intoapache:masterfrom
Conversation
…not exists" (If-None-Match) semantics.
…-create-if-not-exists
…-create-if-not-exists
…-create-if-not-exists
…nt tests and protocol definition.
…-create-if-not-exists
…ion handling - Implemented tests for `createKey` and `rewriteKey` methods to validate behavior when using the `EXPECTED_GEN_CREATE_IF_NOT_EXISTS` constant. - Added scenarios for key creation when the key is absent and when it already exists. - Enhanced the `rewriteFailsWhenKeyExists` test to cover cases for both committed and uncommitted keys. - Updated error handling to ensure correct responses for key existence checks.
…not exists" (If-None-Match) semantics.
…nt tests and protocol definition.
…ion handling - Implemented tests for `createKey` and `rewriteKey` methods to validate behavior when using the `EXPECTED_GEN_CREATE_IF_NOT_EXISTS` constant. - Added scenarios for key creation when the key is absent and when it already exists. - Enhanced the `rewriteFailsWhenKeyExists` test to cover cases for both committed and uncommitted keys. - Updated error handling to ensure correct responses for key existence checks.
jojochuang
left a comment
There was a problem hiding this comment.
from a quick glance it looks mostly reasonable.
hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Show resolved
Hide resolved
…-conditional-writes
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for S3 conditional PUT semantics (If-None-Match: * and If-Match: <etag>) by extending the client RPC API, S3 Gateway PUT handling, and Ozone Manager (create/commit) validation and error mapping.
Changes:
- Extend Ozone client APIs with
createKeyIfNotExistsandrewriteKeyIfMatchand wire them throughRpcClient,ClientProtocol, andOzoneBucket. - Add S3 Gateway conditional header parsing/multiplexing for PUT and translate OM conditional failures to S3
412 PreconditionFailed. - Add OM create/commit validation for
expectedETag, new OM exception/status codes, and comprehensive unit/integration/robot/S3 SDK tests.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectPut.java | Adds unit tests for conditional PUT behavior and ETag parsing. |
| hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneBucketStub.java | Extends test bucket stub with conditional create/rewrite behaviors. |
| hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java | Wires new bucket APIs through the client protocol test stub. |
| hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Consts.java | Defines constants for conditional request headers. |
| hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java | Implements conditional PUT header handling and OM→S3 error translation. |
| hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCreateRequest.java | Adds OM create-phase tests for expected ETag validation. |
| hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCommitRequest.java | Adds OM commit-phase tests for expected ETag validation. |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRequest.java | Propagates expected ETag from request into key info preparation. |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCreateRequest.java | Adds create-phase validation for expectedETag against existing key metadata. |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequestWithFSO.java | Clears expectedETag before persisting committed keys (FSO path). |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequest.java | Clears expectedETag on commit and validates ETag at commit time. |
| hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto | Adds new status codes and expectedETag fields to protocol messages. |
| hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java | Adds integration tests for the new bucket APIs and ETag-based rewrite. |
| hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java | Adds AWS SDK v2 coverage for conditional PUT behaviors. |
| hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java | Adds AWS SDK v1 coverage for conditional PUT behaviors. |
| hadoop-ozone/dist/src/main/smoketest/s3/conditionalput.robot | Adds robot smoketests validating conditional PUT via awscli. |
| hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java | Propagates expected ETag from client args into OM RPC requests. |
| hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java | Persists/serializes the new expectedETag field on key info. |
| hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyArgs.java | Adds expectedETag to OM key args and protobuf conversion. |
| hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java | Adds new OM exception result codes for ETag mismatch/unavailable. |
| hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java | Implements new conditional APIs using expectedDataGeneration / expectedETag. |
| hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java | Exposes new conditional write methods in the client protocol API. |
| hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java | Adds bucket-level wrappers for the new conditional APIs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
Show resolved
Hide resolved
hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
Show resolved
Hide resolved
ivandika3
left a comment
There was a problem hiding this comment.
Thanks @peterxcli for the patch, left initial comments.
...gration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
Show resolved
Hide resolved
…and rewriteIfMatch key in RpcClient
ivandika3
left a comment
There was a problem hiding this comment.
@peterxcli thanks for the update, left additional comments.
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Outdated
Show resolved
Hide resolved
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
Show resolved
Hide resolved
| return Response.ok().status(HttpStatus.SC_OK).build(); | ||
| } | ||
|
|
||
| String ifNoneMatch = getHeaders().getHeaderString( |
There was a problem hiding this comment.
I’m still thinking about how to refactor this(line 283-314), as the conditional request validation logic dominates the function.
There was a problem hiding this comment.
|
@ivandika3 please take another look, Thanks! |
ivandika3
left a comment
There was a problem hiding this comment.
@peterxcli Thanks for the update. LGTM +1.
|
Merged. Thanks @peterxcli and @ivandika3 |
|
Thanks @ivandika3, @jojochuang for reviewing! |
What changes were proposed in this pull request?
createKeyIfNotExists,rewriteKeyIfMatchto RpcClient API, prevent the logic mix wit the existingrewriteKeycreateKeyIfNotExists,rewriteKeyIfMatchandcreateKeyozone/hadoop-hdds/docs/content/design/s3-conditional-requests.md
Lines 59 to 82 in 6c8a08e
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-13919
How was this patch tested?
Clean CI:
https://github.com/peterxcli/ozone/actions/runs/23634401199/job/68841474397