-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[S3 API] Support for S3 AbortMultipartUpload API (#2940)
* Support AbortMultipartUpload for S3 API --------- Co-authored-by: Shan Xu <shaxu@linkedin.com>
- Loading branch information
1 parent
c651bcd
commit e486d69
Showing
11 changed files
with
183 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
ambry-frontend/src/main/java/com/github/ambry/frontend/s3/S3MultipartAbortUploadHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* Copyright 2024 LinkedIn Corp. All rights reserved. | ||
* | ||
* 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. | ||
* | ||
*/ | ||
package com.github.ambry.frontend.s3; | ||
|
||
import com.github.ambry.commons.Callback; | ||
import com.github.ambry.frontend.AccountAndContainerInjector; | ||
import com.github.ambry.frontend.FrontendMetrics; | ||
import com.github.ambry.frontend.SecurityService; | ||
import com.github.ambry.rest.ResponseStatus; | ||
import com.github.ambry.rest.RestRequest; | ||
import com.github.ambry.rest.RestResponseChannel; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import static com.github.ambry.frontend.FrontendUtils.*; | ||
|
||
|
||
/** | ||
* Handles a request for s3 AbortMultipartUploads according to the | ||
* <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html">...</a> | ||
*/ | ||
public class S3MultipartAbortUploadHandler<R> { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(S3MultipartListPartsHandler.class); | ||
private final SecurityService securityService; | ||
private final FrontendMetrics frontendMetrics; | ||
private final AccountAndContainerInjector accountAndContainerInjector; | ||
|
||
/** | ||
* Construct a handler for handling S3 abort multi uploads. | ||
* | ||
* @param securityService the {@link SecurityService} to use. | ||
* @param frontendMetrics {@link FrontendMetrics} instance where metrics should be recorded. | ||
* @param accountAndContainerInjector helper to resolve account and container for a given request. | ||
*/ | ||
public S3MultipartAbortUploadHandler(SecurityService securityService, FrontendMetrics frontendMetrics, | ||
AccountAndContainerInjector accountAndContainerInjector) { | ||
this.securityService = securityService; | ||
this.frontendMetrics = frontendMetrics; | ||
this.accountAndContainerInjector = accountAndContainerInjector; | ||
} | ||
|
||
/** | ||
* @param restRequest the {@link RestRequest} that contains the request parameters. | ||
* @param restResponseChannel the {@link RestResponseChannel} where headers should be set. | ||
* @param callback the {@link Callback} to invoke when the response is ready (or if there is an exception). | ||
*/ | ||
void handle(RestRequest restRequest, RestResponseChannel restResponseChannel, Callback<R> callback) { | ||
new S3MultipartAbortUploadHandler.CallbackChain(restRequest, restResponseChannel, callback).start(); | ||
} | ||
|
||
/** | ||
* Represents the chain of actions to take. Keeps request context that is relevant to all callback stages. | ||
*/ | ||
private class CallbackChain { | ||
private final RestRequest restRequest; | ||
private final RestResponseChannel restResponseChannel; | ||
private final Callback<Void> finalCallback; | ||
private final String uri; | ||
|
||
/** | ||
* @param restRequest the {@link RestRequest}. | ||
* @param restResponseChannel the {@link RestResponseChannel}. | ||
* @param finalCallback the {@link Callback} to call on completion. | ||
*/ | ||
private CallbackChain(RestRequest restRequest, RestResponseChannel restResponseChannel, | ||
Callback<Void> finalCallback) { | ||
this.restRequest = restRequest; | ||
this.restResponseChannel = restResponseChannel; | ||
this.finalCallback = finalCallback; | ||
this.uri = restRequest.getUri(); | ||
} | ||
|
||
/** | ||
* Start the chain by calling {@link SecurityService#processRequest}. | ||
*/ | ||
private void start() { | ||
try { | ||
accountAndContainerInjector.injectAccountContainerForNamedBlob(restRequest, | ||
frontendMetrics.deleteBlobMetricsGroup); | ||
securityService.processRequest(restRequest, securityProcessRequestCallback()); | ||
} catch (Exception e) { | ||
finalCallback.onCompletion(null, e); | ||
} | ||
} | ||
|
||
/** | ||
* After {@link SecurityService#processRequest} finishes, call {@link SecurityService#postProcessRequest} to perform | ||
* request time security checks that rely on the request being fully parsed and any additional arguments set. | ||
* @return a {@link Callback} to be used with {@link SecurityService#processRequest}. | ||
*/ | ||
private Callback<Void> securityProcessRequestCallback() { | ||
return buildCallback(frontendMetrics.s3DeleteHandleMetrics, securityCheckResult -> { | ||
securityService.postProcessRequest(restRequest, securityPostProcessRequestCallback()); | ||
}, uri, LOGGER, finalCallback); | ||
} | ||
|
||
/** | ||
* After {@link SecurityService#postProcessRequest} finishes, return response for the request. | ||
* @return a {@link Callback} to be used with {@link SecurityService#postProcessRequest}. | ||
*/ | ||
private Callback<Void> securityPostProcessRequestCallback() { | ||
return buildCallback(frontendMetrics.s3DeleteHandleMetrics, securityCheckResult -> { | ||
restResponseChannel.setStatus(ResponseStatus.NoContent); | ||
finalCallback.onCompletion(null, null); | ||
}, uri, LOGGER, finalCallback); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.