RUN-4098: migrate s 3 logstorage from v 1 to v 2#62
Conversation
This commit migrates the plugin from AWS SDK v1 (com.amazonaws) to AWS SDK v2 (software.amazon.awssdk).
## Changes Made:
### Dependencies (build.gradle & gradle.properties):
- Added AWS SDK v2 BOM version 2.31.0
- Replaced aws-java-sdk-s3:1.12.777 with software.amazon.awssdk:s3
- Replaced aws-java-sdk-sts:1.12.777 with software.amazon.awssdk:sts
- Added BOM platform dependency to both implementation and pluginLibs configurations
### Core Plugin Code (S3LogFileStoragePlugin.java):
- Updated all AWS SDK imports from v1 to v2
- Removed AWSCredentials interface implementation
- Changed AmazonS3 client field to S3Client
- Rewrote initialize() method:
- Credential handling now uses AwsCredentialsProvider with three methods:
* StaticCredentialsProvider for access key/secret key
* Custom properties file reader for credentials file
* DefaultCredentialsProvider for IAM roles
- Region handling changed from RegionUtils to Region.of()
- Client builder pattern used to configure all options upfront
- S3Configuration used for path style access
- Endpoint override via URI instead of setEndpoint()
- Added warning for signature v2 (not supported in v2)
- Migrated createS3Client() methods with credential provider support
- Migrated isPathAvailable():
- GetObjectMetadataRequest → HeadObjectRequest
- ObjectMetadata → HeadObjectResponse
- AmazonS3Exception → S3Exception
- Migrated createObjectMetadata() to return Map<String, String>
- Migrated storePath():
- Changed signature to accept content length and metadata map
- Uses PutObjectRequest builder with RequestBody
- S3Exception instead of AmazonClientException
- Migrated retrievePath():
- GetObject → ResponseInputStream<GetObjectResponse>
- Uses ResponseTransformer.toInputStream()
- Migrated deleteFile():
- Uses DeleteObjectRequest builder
- Updated getAmazonS3() → getS3Client()
### Build Status:
✅ Plugin compiles successfully
✅ JAR builds successfully (12MB)
⚠️ Unit tests not migrated yet (require AWS SDK v2 updates)
### Breaking Changes:
- Signature V2 no longer supported (logs warning, uses V4)
- Method signature changes for internal methods
- getAmazonS3() renamed to getS3Client()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR migrates the S3LogFileStoragePlugin from AWS SDK v1 to AWS SDK v2 and updates the tests and build configuration accordingly, while also tightening configuration validation and modernizing the S3 interaction patterns.
Changes:
- Replace all AWS SDK v1 S3 types/usages in
S3LogFileStoragePluginwith AWS SDK v2 equivalents (S3Client,HeadObjectRequest,PutObjectRequest,GetObjectRequest,S3Exception,SdkClientException,RequestBody, etc.), and introduce a configurableS3Clientbuilder using v2 credential providers. - Refactor and extend tests around credentials, region/endpoint handling, metadata, availability checks, and store/retrieve/delete operations using a new
MockS3Client, removing the large v1-specificFailS3test harness. - Update Gradle configuration to use the AWS SDK v2 BOM and S3/STS modules via
awsSdkBomVersion, aligning plugin packaging (pluginLibs) with the new dependency set.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/main/java/org/rundeck/plugins/S3LogFileStoragePlugin.java |
Migrates the core S3 log storage implementation from AWS SDK v1 to v2 (client creation, credential handling, head/get/put/delete operations, and metadata handling), adds region-name validation against software.amazon.awssdk.regions.Region, and adapts path/bucket validation while preserving plugin behavior. |
src/test/java/org/rundeck/plugins/S3LogFileStoragePluginTest.java |
Updates existing tests to exercise the SDK v2-based implementation, including new assertions for credentials-file validation messages, region validation, metadata contents, and exception messages, and rewrites S3 behavior expectations to work through MockS3Client. |
src/test/java/org/rundeck/plugins/MockS3Client.java |
Introduces a focused SDK v2-style S3Client mock that simulates headObject, getObject, putObject, and deleteObject behaviors (including error paths and recorded parameters) for deterministic testing of the plugin without AWS. |
src/test/java/org/rundeck/plugins/FailS3.java |
Removes the large AWS SDK v1–specific AbstractAmazonS3 test stub in favor of the leaner MockS3Client tailored to the v2 API. |
build.gradle |
Replaces v1 aws-java-sdk-s3/aws-java-sdk-sts dependencies with the AWS SDK v2 BOM and software.amazon.awssdk:s3/software.amazon.awssdk:sts modules for both implementation and pluginLibs, excluding slf4j and Jackson to avoid conflicts. |
gradle.properties |
Adds the awsSdkBomVersion property (set to 2.33.13) to control the AWS SDK v2 BOM version used in the build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| logger.warn("Signature V2 is not supported in AWS SDK v2. Using Signature V4 instead."); | ||
| } | ||
| if (isSignatureV4Enforced()) { | ||
| logger.debug("Signature V4 is enforced by default in AWS SDK v2"); |
There was a problem hiding this comment.
The useSigV2 and forceSigV4 plugin properties are now effectively no-ops under AWS SDK v2 (the client always uses Signature V4, and this code only logs when those flags are set), but the @PluginProperty descriptions still imply they control the signature behavior. To avoid confusing users, consider updating the property descriptions (or marking them as deprecated) to explain that Signature V2 is no longer supported and Signature V4 is always used by the SDK.
| logger.warn("Signature V2 is not supported in AWS SDK v2. Using Signature V4 instead."); | |
| } | |
| if (isSignatureV4Enforced()) { | |
| logger.debug("Signature V4 is enforced by default in AWS SDK v2"); | |
| logger.warn("The 'useSigV2' property is deprecated and ignored: Signature V2 is not supported in AWS SDK v2; Signature V4 is always used instead."); | |
| } | |
| if (isSignatureV4Enforced()) { | |
| logger.debug("The 'forceSigV4' property is deprecated and has no effect: AWS SDK v2 always uses Signature V4 for S3 requests."); |
| HashMap<String, Object> expected = new HashMap<>(); | ||
| expected.put(metaKey(META_EXECID), context.get(META_ID_FOR_LOGSTORE)); |
There was a problem hiding this comment.
In deleteFile, the expected metadata map is constructed but never used, which adds noise and can mislead future readers into thinking there is some metadata-based delete verification. If no metadata check is intended here, you can safely remove the expected map; otherwise, consider wiring it into a precondition check before issuing the delete.
| HashMap<String, Object> expected = new HashMap<>(); | |
| expected.put(metaKey(META_EXECID), context.get(META_ID_FOR_LOGSTORE)); |
| // Configure S3-specific options (path style access) | ||
| if (isPathStyle()) { | ||
| clientBuilder.serviceConfiguration( | ||
| S3Configuration.builder() | ||
| .pathStyleAccessEnabled(true) | ||
| .build()); |
There was a problem hiding this comment.
The new path-style configuration using S3Configuration.builder().pathStyleAccessEnabled(true) is not covered by tests, and the previous tests that exercised setPathStyle(true) behavior were removed. It would be good to add a unit test that verifies that enabling pathStyle on the plugin results in a client configured for path-style access (e.g., by inspecting the constructed client or a wrapper) to ensure this behavior doesn’t regress.
| # Main dependency versions | ||
| rundeckVersion=5.16.0-20251006 | ||
| awsSdkVersion=1.12.777 | ||
| awsSdkBomVersion=2.33.13 |
There was a problem hiding this comment.
The PR description states that awsSdkBomVersion is being set to 2.31.0, but the actual value here is 2.33.13. Please update either the description or this property so they are consistent, or briefly call out the intentional discrepancy.
| private Region region; | ||
| private String endpoint; | ||
| private S3Object getObject; | ||
| class testS3 extends MockS3Client { |
There was a problem hiding this comment.
testS3 should be made static, since the enclosing instance is not used.
| class testS3 extends MockS3Client { | |
| static class testS3 extends MockS3Client { |
| } | ||
|
|
||
| // Set region or endpoint | ||
| if (null == getEndpoint() || "".equals(getEndpoint().trim())) { |
There was a problem hiding this comment.
Inefficient comparison to empty string, check for zero length instead.
JIRA ticket: https://pagerduty.atlassian.net/browse/RUN-4098
This pull request migrates the
S3LogFileStoragePluginfrom AWS SDK v1 to AWS SDK v2, modernizing the codebase and improving maintainability. The migration required significant changes to how S3 clients are configured, credentials are handled, and S3 operations are performed. The update also improves error handling and configuration validation.Key changes include:
AWS SDK v2 Migration:
AmazonS3,AWSCredentials, and related classes) with AWS SDK v2 equivalents (such asS3Client,AwsCredentialsProvider, etc.) throughoutS3LogFileStoragePlugin.java.S3Clientand AWS SDK v2 credential providers, including support for static credentials, credentials files, and the default provider chain. [1] [2]S3Client,PutObjectRequest,HeadObjectRequest,S3Exception, etc.). [1] [2] [3] [4] [5]Configuration and Validation Improvements:
Metadata Handling:
Map<String, String>instead of AWS SDK v1'sObjectMetadata.Dependency Management:
awsSdkBomVersion=2.31.0togradle.propertiesto track the new AWS SDK v2 dependency version.These changes collectively bring the plugin up to date with current AWS SDK best practices and lay the groundwork for future enhancements.