-
Notifications
You must be signed in to change notification settings - Fork 594
HDDS-13532. Refactor BucketEndpoint.get() method #9110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
peterxcli
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rich7420 for the patch. Please enable the build-branch workflow in your fork.
#9102 (review)
BTW, curious why we need these three new tests?
|
Thanks, @rich7420, for the patch. Please move the integration tests to the integration module instead of keeping them with the unit tests. Also, it would be helpful if you could add some context explaining the purpose of these test cases. |
|
@peterxcli , @priyeshkaratha Thanks for the review! |
|
I’ve enabled the build-branch workflow on my fork. https://github.com/rich7420/ozone/actions/runs/18313906976/job/52148987227 |
| /** | ||
| * Simple unit tests for the refactored BucketEndpoint methods. | ||
| */ | ||
| public class TestBucketEndpointRefactoredSimple { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest to rename it as TestBucketEndpoint
| AUDIT.logReadSuccess( | ||
| buildAuditMessageForSuccess(s3GAction, getAuditParameters())); | ||
| return Response.ok(result, MediaType.APPLICATION_XML_TYPE).build(); | ||
| return handleAclRequest(bucketName, startNanos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest to rename as handleGetBucketAcl because it implements GetBucketAcl https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html
| /** | ||
| * Process key listing logic. | ||
| */ | ||
| void processKeyListing(BucketListingContext context, ListObjectResponse response) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this method doesn't touch anything inside BucketEndpoint, and that it accesses BucketListingContext, then perhaps it's better placed inside BucketListingContext.
hevinhsu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rich7420 for updating the patch. Overall LGTM. Left some comments.
| bucketEndpoint = new BucketEndpoint(); | ||
| OzoneClientStub client = new OzoneClientStub(); | ||
|
|
||
| bucketEndpoint.setClient(client); | ||
| bucketEndpoint.setRequestIdentifier(new RequestIdentifier()); | ||
| bucketEndpoint.setOzoneConfiguration(new OzoneConfiguration()); | ||
| bucketEndpoint.init(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can use a builder to simplify the endpoint creation:
| bucketEndpoint = new BucketEndpoint(); | |
| OzoneClientStub client = new OzoneClientStub(); | |
| bucketEndpoint.setClient(client); | |
| bucketEndpoint.setRequestIdentifier(new RequestIdentifier()); | |
| bucketEndpoint.setOzoneConfiguration(new OzoneConfiguration()); | |
| bucketEndpoint.init(); | |
| OzoneClientStub client = new OzoneClientStub(); | |
| bbucketEndpoint = EndpointBuilder.newBucketEndpointBuilder() | |
| .setClient(client) | |
| .build(); |
| bucketEndpoint.init(); | ||
|
|
||
| // Create a test bucket | ||
| client.getObjectStore().createS3Bucket("test-bucket"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like all test cases use the same bucketName. Maybe we can extract it into a shared variable.
| // If you specify the encoding-type request parameter,should return | ||
| // encoded key name values in the following response elements: | ||
| // Delimiter, Prefix, Key, and StartAfter. | ||
| // | ||
| // For detail refer: | ||
| // https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html | ||
| // #AmazonS3-ListObjectsV2-response-EncodingType | ||
| // |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this comment be keep?
|
@jojochuang @hevinhsu @TaiJuWu Thanks a lot for the suggestions! I’ve implemented the updates that switched tests to use EndpointBuilder for endpoint creation, moved the key-listing logic into BucketListingContext with BucketEndpoint.processKeyListing(...) delegating to it, renamed the method to handleGetBucketAcl(...), added throws IOException to the test helper getObjectEndpoint(...), and fixed the trailing newline and related style checks. CI is all green now. If there’s anything else we can refine, I’m happy to follow up. |
hevinhsu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rich7420 for continuously improving this patch. Overall it LGTM, I've just left a few comments below.
| @QueryParam("upload-id-marker") String uploadIdMarker, | ||
| @DefaultValue("1000") @QueryParam("max-uploads") int maxUploads) throws OS3Exception, IOException { | ||
| long startNanos = Time.monotonicNowNanos(); | ||
| S3GAction s3GAction = S3GAction.GET_BUCKET; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Maybe we can move this line to where the actual bucket processing starts, for better readability — similar to how you declared s3GAction at the beginning of the actual process block in handleGetBucketAcl and listMultipartUploads.
| // Return empty response if no keys found | ||
| ListObjectResponse emptyResponse = new ListObjectResponse(); | ||
| emptyResponse.setName(bucketName); | ||
| emptyResponse.setKeyCount(0); | ||
| return Response.ok(emptyResponse).build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems you chose another approach to handle the FILE_NOT_FOUND case when no key is found.
Previously, the exception was caught and the get bucket process continued, ensuring the audit log was written afterward.
In your version, this logic is handled in a separate block that returns an empty response, but it seems the audit log is not written in this path.
Maybe we should also log the audit entry here to align with the previous behavior.
|
This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days. |
jojochuang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this.
In a typical refactoring effort, the behavior of the code change should stay exactly the same. However, it doesn't look like so especially the exception handling.
| // Handle ACL requests | ||
| if (aclMarker != null) { | ||
| return handleGetBucketAcl(bucketName, startNanos); | ||
| } | ||
|
|
||
| maxKeys = validateMaxKeys(maxKeys); | ||
| // Handle multipart uploads requests | ||
| if (uploads != null) { | ||
| return listMultipartUploads(bucketName, prefix, keyMarker, uploadIdMarker, maxUploads); | ||
| } | ||
|
|
||
| if (prefix == null) { | ||
| prefix = ""; | ||
| } | ||
| // Actual bucket processing starts here | ||
| S3GAction s3GAction = S3GAction.GET_BUCKET; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these lines should go into the try block below.
|
@jojochuang Thanks for the review! I'll fix it as soon as possible |
|
This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days. |
|
Thanks @rich7420 for working on this. In HDDS-14123 we started to move logic into separate handler classes. E.g. |
|
This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days. |
What changes were proposed in this pull request?
This PR refactors the
BucketEndpoint.get()method to improve code maintainability and readability.The original method was nearly 200 lines long and contained multiple unrelated logic blocks, making it difficult to understand, test, and maintain.
Changes in this PRr
get()methodBucketListingContextclass to encapsulate parametersWhat is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-13532
How was this patch tested?
TestBucketEndpointRefactoredSimple.javaTestBucketEndpointIntegration.javaTestBucketEndpointPerformance.java