Repository: aws/aws-sdk-java-v2
Pull request #6059: Added support for s3-event-notifications in migration tool
Author: login: Fred1155
Created: 2025-04-24T23:44:08Z | Merged: 2025-05-02T00:08:08Z

<!--- Provide a general summary of your changes in the Title above -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here -->
This PR added support for s3-event-notifications in migration tool. s3-event-notifications is a separate module in v2, while in v1 it is in s3.event folder. All nested class in S3EventNotification class in v1 is a separated class in v2.
## Modifications
<!--- Describe your changes in detail -->
Added transform for all package names.
Added transform for all different method names.
Added transform for different return types (getEventNameAsEnum() and getEventTime())
Added recipe to add wrapper for methods that return DateTime in v1 and Instant in v2
## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
Added new integration test class for s3-event-notifications module
## Screenshots (if appropriate)

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)

## Checklist
<!--- Go over all the following points, and put an `x` in all the boxes that apply -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] I have read the [CONTRIBUTING](https://github.com/aws/aws-sdk-java-v2/blob/master/CONTRIBUTING.md) document
- [x] Local run of `mvn install` succeeds
- [x] My code follows the code style of this project
- [ ] My change requires a change to the Javadoc documentation
- [ ] I have updated the Javadoc documentation accordingly
- [x] I have added tests to cover my changes
- [x] All new and existing tests passed
- [ ] I have added a changelog entry. Adding a new entry must be accomplished by running the `scripts/new-change` script and following the instructions. Commit the new file created by the script in `.changes/next-release` with your changes.
- [ ] My change is to implement 1.11 parity feature and I have updated [LaunchChangelog](https://github.com/aws/aws-sdk-java-v2/blob/master/docs/LaunchChangelog.md)

## License
<!--- The SDK is released under the Apache 2.0 license (http://aws.amazon.com/apache2.0/), so any code you submit will be released under that license -->
<!--- For substantial contributions, we may ask you to sign a Contributor License Agreement (http://en.wikipedia.org/wiki/Contributor_License_Agreement) -->
<!--- Put an `x` in the below box if you confirm that this request can be released under the Apache 2 license -->
- [x] I confirm that this pull request can be released under the Apache 2 license



Diff:
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/pom.xml b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/pom.xml
index cd6274a6a517..f1b3db956b61 100644
--- a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/pom.xml
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/pom.xml
@@ -46,6 +46,11 @@
             <artifactId>s3</artifactId>
             <version>V2_VERSION</version>
         </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>s3-event-notifications</artifactId>
+            <version>V2_VERSION</version>
+        </dependency>
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>s3-transfer-manager</artifactId>
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3EnDateTime.java b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3EnDateTime.java
new file mode 100644
index 000000000000..bee0b278b9af
--- /dev/null
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3EnDateTime.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import org.joda.time.DateTime;
+
+public class S3EnDateTime {
+
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotification.S3EventNotificationRecord record : notification.getRecords()) {
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
+            GlacierEventData glacierEventData = record.getGlacierEventData();
+
+            RestoreEventData restoreEventData = glacierEventData.getRestoreEventData();
+
+            DateTime expireTime = /*AWS SDK for Java v2 migration: getLifecycleRestorationExpiryTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(restoreEventData.getLifecycleRestorationExpiryTime().toEpochMilli());
+
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3Transforms.java b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3Transforms.java
index 2b20f4b92707..e2bd389664dd 100644
--- a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3Transforms.java
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/after/src/main/java/foo/bar/S3Transforms.java
@@ -18,10 +18,6 @@
 import com.amazonaws.HttpMethod;
 import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams;
 import com.amazonaws.services.s3.model.SSECustomerKey;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Date;
 import software.amazon.awssdk.core.async.AsyncRequestBody;
 import software.amazon.awssdk.services.s3.S3Client;
 import software.amazon.awssdk.services.s3.model.AccessControlPolicy;
@@ -34,6 +30,11 @@
 import software.amazon.awssdk.transfer.s3.S3TransferManager;
 import software.amazon.awssdk.transfer.s3.model.UploadRequest;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Date;
+
 public class S3Transforms {
 
     S3Client s3;
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/before/src/main/java/foo/bar/S3EnDateTime.java b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/before/src/main/java/foo/bar/S3EnDateTime.java
new file mode 100644
index 000000000000..a2faa2a53e8c
--- /dev/null
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-nocompile/before/src/main/java/foo/bar/S3EnDateTime.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import com.amazonaws.services.s3.event.S3EventNotification;
+import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;
+import com.amazonaws.services.s3.event.S3EventNotification.RestoreEventDataEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.GlacierEventDataEntity;
+import com.amazonaws.services.s3.model.S3Event;
+import org.joda.time.DateTime;
+
+public class S3EnDateTime {
+
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.parseJson(jsonInput);
+
+        for (S3EventNotification.S3EventNotificationRecord record : notification.getRecords()) {
+            DateTime eventTime = record.getEventTime();
+
+            GlacierEventDataEntity glacierEventData = record.getGlacierEventData();
+
+            RestoreEventDataEntity restoreEventData = glacierEventData.getRestoreEventData();
+
+            DateTime expireTime = restoreEventData.getLifecycleRestorationExpiryTime();
+
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/pom.xml b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/pom.xml
index c4fa83bdc7a0..693894ce86eb 100644
--- a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/pom.xml
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/pom.xml
@@ -57,6 +57,11 @@
             <artifactId>netty-nio-client</artifactId>
             <version>V2_VERSION</version>
         </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>s3-event-notifications</artifactId>
+            <version>V2_VERSION</version>
+        </dependency>
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>s3</artifactId>
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/src/main/java/foo/bar/S3EventNotificationTest.java b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/src/main/java/foo/bar/S3EventNotificationTest.java
new file mode 100644
index 000000000000..16dcc8b5892d
--- /dev/null
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/after/src/main/java/foo/bar/S3EventNotificationTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            RequestParameters requestParams = record.getRequestParameters();
+
+            ResponseElements responseElements = record.getResponseElements();
+
+            UserIdentity userIdentity = record.getUserIdentity();
+
+            GlacierEventData glacierEventData = record.getGlacierEventData();
+
+            RestoreEventData restoreEventData = glacierEventData.getRestoreEventData();
+
+            LifecycleEventData lifecycleEventData = record.getLifecycleEventData();
+
+            IntelligentTieringEventData intelligentTieringEventData = record.getIntelligentTieringEventData();
+
+            ReplicationEventData replicationEventData = record.getReplicationEventData();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/before/src/main/java/foo/bar/S3EventNotificationTest.java b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/before/src/main/java/foo/bar/S3EventNotificationTest.java
new file mode 100644
index 000000000000..40c92bc94e15
--- /dev/null
+++ b/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven/before/src/main/java/foo/bar/S3EventNotificationTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import com.amazonaws.services.s3.event.S3EventNotification;
+import com.amazonaws.services.s3.event.S3EventNotification.S3BucketEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.S3Entity;
+import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;
+import com.amazonaws.services.s3.event.S3EventNotification.S3ObjectEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.RequestParametersEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.ResponseElementsEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.RestoreEventDataEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.UserIdentityEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.GlacierEventDataEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.LifecycleEventDataEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.IntelligentTieringEventDataEntity;
+import com.amazonaws.services.s3.event.S3EventNotification.ReplicationEventDataEntity;
+import com.amazonaws.services.s3.model.S3Event;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.parseJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3Entity s3 = record.getS3();
+
+            S3BucketEntity bucket = s3.getBucket();
+
+            S3ObjectEntity object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            S3Event eventNameEnum = record.getEventNameAsEnum();
+
+            RequestParametersEntity requestParams = record.getRequestParameters();
+
+            ResponseElementsEntity responseElements = record.getResponseElements();
+
+            UserIdentityEntity userIdentity = record.getUserIdentity();
+
+            GlacierEventDataEntity glacierEventData = record.getGlacierEventData();
+
+            RestoreEventDataEntity restoreEventData = glacierEventData.getRestoreEventData();
+
+            LifecycleEventDataEntity lifecycleEventData = record.getLifecycleEventData();
+
+            IntelligentTieringEventDataEntity intelligentTieringEventData = record.getIntelligentTieringEventData();
+
+            ReplicationEventDataEntity replicationEventData = record.getReplicationEventDataEntity();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3AddImportsAndComments.java b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3AddImportsAndComments.java
index 3f23bc31aa68..ff8a55c2597d 100644
--- a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3AddImportsAndComments.java
+++ b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3AddImportsAndComments.java
@@ -18,6 +18,7 @@
 import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.V1_S3_MODEL_PKG;
 import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.V2_S3_MODEL_PKG;
 import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.createComments;
+import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.v1EnMethodMatcher;
 import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.v1S3MethodMatcher;
 
 import java.util.List;
@@ -52,6 +53,10 @@ public class S3AddImportsAndComments extends Recipe {
     private static final MethodMatcher SELECT_OBJECT_CONTENT = v1S3MethodMatcher("selectObjectContent(..)");
     private static final MethodMatcher SET_LIFECYCLE_CONFIGURATION = v1S3MethodMatcher("setBucketLifecycleConfiguration(..)");
     private static final MethodMatcher SET_TAGGING_CONFIGURATION = v1S3MethodMatcher("setBucketTaggingConfiguration(..)");
+    private static final MethodMatcher GET_EVENT_TIME = v1EnMethodMatcher("S3EventNotification.S3EventNotificationRecord "
+                                                                          + "getEventTime(..)");
+    private static final MethodMatcher  GET_EXPIRY_TIME = v1EnMethodMatcher("S3EventNotification.RestoreEventDataEntity "
+                                                                            + "getLifecycleRestorationExpiryTime(..)");
 
 
     private static final Pattern CANNED_ACL = Pattern.compile(V1_S3_MODEL_PKG + "CannedAccessControlList");
@@ -191,6 +196,13 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
                 return method.withComments(createComments(comment));
             }
 
+            if (GET_EVENT_TIME.matches(method) || GET_EXPIRY_TIME.matches(method)) {
+                String comment = method.getSimpleName() + " returns Instant instead of DateTime in v2. AWS SDK v2 does not "
+                                 + "include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to "
+                                 + "manually add \"org.joda.time:joda-time\" dependency to your"
+                                 + " project after migration.";
+                return method.withComments(createComments(comment));
+            }
             return method;
         }
 
diff --git a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3EventNotificationMethodToV2.java b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3EventNotificationMethodToV2.java
new file mode 100644
index 000000000000..c5267d642f69
--- /dev/null
+++ b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/S3EventNotificationMethodToV2.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.v2migration;
+
+import static software.amazon.awssdk.v2migration.internal.utils.S3TransformUtils.v1EnMethodMatcher;
+
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.java.JavaTemplate;
+import org.openrewrite.java.JavaVisitor;
+import org.openrewrite.java.MethodMatcher;
+import org.openrewrite.java.tree.J;
+import software.amazon.awssdk.annotations.SdkInternalApi;
+
+@SdkInternalApi
+public class S3EventNotificationMethodToV2 extends Recipe {
+
+    private static final MethodMatcher GET_EVENT_TIME = v1EnMethodMatcher("S3EventNotification.S3EventNotificationRecord "
+                                                                          + "getEventTime(..)");
+
+    private static final MethodMatcher  GET_EXPIRY_TIME = v1EnMethodMatcher("S3EventNotification.RestoreEventDataEntity "
+                                                                          + "getLifecycleRestorationExpiryTime(..)");
+
+    @Override
+    public String getDisplayName() {
+        return "S3 Event Notification method to v2";
+    }
+
+    @Override
+    public String getDescription() {
+        return "S3 Event Notification method to v2";
+    }
+
+    @Override
+    public TreeVisitor<?, ExecutionContext> getVisitor() {
+        return new Visitor();
+    }
+
+    private static class Visitor extends JavaVisitor<ExecutionContext> {
+        @Override
+        public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
+            if (GET_EVENT_TIME.matches(method) || GET_EXPIRY_TIME.matches(method)) {
+                JavaTemplate template = JavaTemplate.builder("new DateTime(#{any(java.time.Instant)}.toEpochMilli())")
+                                                    .build();
+                J m = super.visitMethodInvocation(method, ctx);
+                m = template.apply(getCursor(), ((J.MethodInvocation) m).getCoordinates().replace(), m);
+                return m;
+            }
+            return method;
+        }
+
+    }
+
+}
diff --git a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/S3TransformUtils.java b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/S3TransformUtils.java
index eda4a98a5a87..2a4895952edc 100644
--- a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/S3TransformUtils.java
+++ b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/S3TransformUtils.java
@@ -37,6 +37,7 @@ public final class S3TransformUtils {
     public static final String V1_S3_CLIENT = "com.amazonaws.services.s3.AmazonS3";
     public static final String V1_S3_MODEL_PKG = "com.amazonaws.services.s3.model.";
     public static final String V1_S3_PKG = "com.amazonaws.services.s3.";
+    public static final String V1_EN_PKG = "com.amazonaws.services.s3.event.";
 
     public static final String V2_S3_CLIENT = "software.amazon.awssdk.services.s3.S3Client";
     public static final String V2_S3_MODEL_PKG = "software.amazon.awssdk.services.s3.model.";
@@ -77,6 +78,10 @@ public static MethodMatcher v1S3MethodMatcher(String methodSignature) {
         return new MethodMatcher(V1_S3_CLIENT + " " + methodSignature, true);
     }
 
+    public static MethodMatcher v1EnMethodMatcher(String methodSignature) {
+        return new MethodMatcher(V1_EN_PKG + methodSignature, true);
+    }
+
     public static MethodMatcher v2S3MethodMatcher(String methodSignature) {
         return new MethodMatcher(V2_S3_CLIENT + " " + methodSignature, true);
     }
diff --git a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/SdkTypeUtils.java b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/SdkTypeUtils.java
index 2aa13502b9ca..da0ad412b90b 100644
--- a/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/SdkTypeUtils.java
+++ b/v2-migration/src/main/java/software/amazon/awssdk/v2migration/internal/utils/SdkTypeUtils.java
@@ -174,6 +174,7 @@ public final class SdkTypeUtils {
         CLASSES_TO_SKIP.add(V1_S3_MODEL_PKG + "S3ObjectId");
         CLASSES_TO_SKIP.add(V1_S3_MODEL_PKG + "S3ObjectIdBuilder");
         CLASSES_TO_SKIP.add(V1_S3_MODEL_PKG + "TagSet");
+        CLASSES_TO_SKIP.add(V1_S3_MODEL_PKG + "SelectObjectContentEvent");
 
         // S3 Enums with no v2 equivalent
         CLASSES_TO_SKIP.add(V1_S3_MODEL_PKG + "GroupGrantee");
diff --git a/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2-with-tm.yml b/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2-with-tm.yml
index 99b4b6991845..1409d4f853c0 100644
--- a/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2-with-tm.yml
+++ b/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2-with-tm.yml
@@ -22,17 +22,21 @@ tags:
   - sdk
 recipeList:
   - software.amazon.awssdk.v2migration.AddTransferManagerDependency
+  - software.amazon.awssdk.v2migration.AddS3EventNotificationDependency
   - software.amazon.awssdk.v2migration.UpgradeSdkDependencies
   - software.amazon.awssdk.v2migration.S3AddImportsAndComments
+  - software.amazon.awssdk.v2migration.S3EventNotificationMethodToV2
   - software.amazon.awssdk.v2migration.S3TypesToV2
   - software.amazon.awssdk.v2migration.S3StreamingResponseToV2
   - software.amazon.awssdk.v2migration.S3StreamingRequestToV2
   - software.amazon.awssdk.v2migration.S3NonStreamingRequestToV2
   - software.amazon.awssdk.v2migration.S3MethodsToV2
+  - software.amazon.awssdk.v2migration.S3EventNotificationMethodsToV2
   - software.amazon.awssdk.v2migration.S3MethodsConstructorToFluent
   - software.amazon.awssdk.v2migration.S3UriToV2
   - software.amazon.awssdk.v2migration.EnumGettersToV2
   - software.amazon.awssdk.v2migration.ChangeTransferManagerTypes
+  - software.amazon.awssdk.v2migration.ChangeS3EventNotificationTypes
   - software.amazon.awssdk.v2migration.ChangeSdkType
   - software.amazon.awssdk.v2migration.ChangeSdkCoreTypes
   # At this point, all classes should be changed to v2 equivalents
diff --git a/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml b/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml
index f6b624998e48..3c4f420719f5 100644
--- a/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml
+++ b/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml
@@ -21,16 +21,20 @@ tags:
   - aws
   - sdk
 recipeList:
+  - software.amazon.awssdk.v2migration.AddS3EventNotificationDependency
   - software.amazon.awssdk.v2migration.UpgradeSdkDependencies
   - software.amazon.awssdk.v2migration.S3AddImportsAndComments
+  - software.amazon.awssdk.v2migration.S3EventNotificationMethodToV2
   - software.amazon.awssdk.v2migration.S3TypesToV2
   - software.amazon.awssdk.v2migration.S3StreamingResponseToV2
   - software.amazon.awssdk.v2migration.S3StreamingRequestToV2
   - software.amazon.awssdk.v2migration.S3NonStreamingRequestToV2
   - software.amazon.awssdk.v2migration.S3MethodsToV2
+  - software.amazon.awssdk.v2migration.S3EventNotificationMethodsToV2
   - software.amazon.awssdk.v2migration.S3MethodsConstructorToFluent
   - software.amazon.awssdk.v2migration.S3UriToV2
   - software.amazon.awssdk.v2migration.EnumGettersToV2
+  - software.amazon.awssdk.v2migration.ChangeS3EventNotificationTypes
   - software.amazon.awssdk.v2migration.ChangeSdkType
   - software.amazon.awssdk.v2migration.ChangeSdkCoreTypes
   # At this point, all classes should be changed to v2 equivalents
diff --git a/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-methods.yml b/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-methods.yml
new file mode 100644
index 000000000000..d43fc06bdb39
--- /dev/null
+++ b/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-methods.yml
@@ -0,0 +1,34 @@
+#
+# Copyright Amazon.com, Inc. or its affiliates. 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.
+# A copy of the License is located at
+#
+#  http://aws.amazon.com/apache2.0
+#
+# or in the "license" file accompanying this file. This file 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.
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: software.amazon.awssdk.v2migration.S3EventNotificationMethodsToV2
+displayName: Change S3EventNotification methods to v2.
+description: Change S3EventNotification methods to v2.
+recipeList:
+  - software.amazon.awssdk.v2migration.openrewrite.ChangeMethodInvocationReturnType:
+      methodPattern: com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord getEventNameAsEnum()
+      newReturnType: String
+  - org.openrewrite.java.ChangeMethodName:
+      methodPattern: com.amazonaws.services.s3.event.S3EventNotification.GlacierEventDataEntity getRestoreEventDataEntity()
+      newMethodName: getRestoreEventData
+  - org.openrewrite.java.ChangeMethodName:
+      methodPattern: com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord getEventNameAsEnum()
+      newMethodName: getEventName
+  - org.openrewrite.java.ChangeMethodName:
+      methodPattern: com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord getReplicationEventDataEntity()
+      newMethodName: getReplicationEventData
+  - org.openrewrite.java.ChangeMethodName:
+      methodPattern: com.amazonaws.services.s3.event.S3EventNotification parseJson(String)
+      newMethodName: fromJson
\ No newline at end of file
diff --git a/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-types.yml b/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-types.yml
new file mode 100644
index 000000000000..32c7efcc1cb1
--- /dev/null
+++ b/v2-migration/src/main/resources/META-INF/rewrite/change-s3-event-notification-types.yml
@@ -0,0 +1,62 @@
+#
+# Copyright Amazon.com, Inc. or its affiliates. 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.
+# A copy of the License is located at
+#
+#  http://aws.amazon.com/apache2.0
+#
+# or in the "license" file accompanying this file. This file 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.
+#
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: software.amazon.awssdk.v2migration.ChangeS3EventNotificationTypes
+displayName: Change SDK S3EventNotification types from v1 to v2
+description: Change SDK S3EventNotification types from v1 to v2.
+recipeList:
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.GlacierEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.IntelligentTieringEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.LifecycleEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.ReplicationEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.RequestParametersEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.RequestParameters
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.ResponseElementsEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.ResponseElements
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.RestoreEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.S3BucketEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.S3Bucket
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.S3Entity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.S3
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.S3ObjectEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.S3Object
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.TransitionEventDataEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.TransitionEventData
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification.UserIdentityEntity
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.UserIdentity
+  - org.openrewrite.java.ChangeType:
+      oldFullyQualifiedTypeName: com.amazonaws.services.s3.event.S3EventNotification
+      newFullyQualifiedTypeName: software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification
\ No newline at end of file
diff --git a/v2-migration/src/main/resources/recipe-vm-templates/add-s3-event-notification-dependency.yml.vm b/v2-migration/src/main/resources/recipe-vm-templates/add-s3-event-notification-dependency.yml.vm
new file mode 100644
index 000000000000..eedb1cb23732
--- /dev/null
+++ b/v2-migration/src/main/resources/recipe-vm-templates/add-s3-event-notification-dependency.yml.vm
@@ -0,0 +1,28 @@
+#
+# Copyright Amazon.com, Inc. or its affiliates. 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.
+# A copy of the License is located at
+#
+#  http://aws.amazon.com/apache2.0
+#
+# or in the "license" file accompanying this file. This file 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.
+#
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: software.amazon.awssdk.v2migration.AddS3EventNotificationDependency
+displayName: Add AWS SDK for Java v2 S3 Event Notification dependency if needed
+description: This recipe will add the Java v2 S3 Event Notification dependency if v1 S3EventNotification is used
+tags:
+  - aws
+  - sdk
+recipeList:
+  - org.openrewrite.java.dependencies.AddDependency:
+      groupId: software.amazon.awssdk
+      artifactId: s3-event-notifications
+      version: ${sdkVersion}
+      onlyIfUsing: com.amazonaws.services.s3.event.S3EventNotification
\ No newline at end of file


Reviews:
user: login: dagnir
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T20:50:18Z
user: login: davidh44
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T21:06:38Z
user: login: davidh44
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T21:16:44Z
user: login: davidh44
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T22:10:23Z
user: login: dagnir
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T01:50:10Z
user: login: Fred1155
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T16:29:55Z
user: login: dagnir
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T19:50:48Z
user: login: Fred1155
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T19:55:01Z
user: login: dagnir
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T21:19:09Z
user: login: davidh44
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T21:33:16Z

Review comments:
diff_hunk: @@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+import org.joda.time.DateTime;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
path: test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-en/after/src/main/java/foo/bar/S3EventNotificationTest.java
user: login: dagnir
body: Is it possible to put these comments above the statement?
created_at: 2025-04-30T20:47:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+import org.joda.time.DateTime;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
path: test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-en/after/src/main/java/foo/bar/S3EventNotificationTest.java
user: login: davidh44
body: Not easily, we are visiting the method invocation here, and would have to check if there is a variable assignment and add it there instead if so. Even then, putting a newline after the comment causes the code to have no indentation, which is why I didn't do it for other comments.

I'd imagine users would remove all comments regardless so I think its okay
created_at: 2025-04-30T21:06:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -21,16 +21,20 @@ tags:
   - aws
   - sdk
 recipeList:
+  - software.amazon.awssdk.v2migration.AddS3EventNotificationDependency
path: v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml
user: login: davidh44
body: We should update tm recipe as well (which includes all of this recipe)

https://github.com/aws/aws-sdk-java-v2/blob/master/v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2-with-tm.yml
created_at: 2025-04-30T21:16:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,54 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.v2migrationtests;
+
+import static software.amazon.awssdk.v2migrationtests.TestUtils.replaceVersion;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIf;
+
+public class MavenS3EventNotificationTest extends MavenTestBase {
path: test/v2-migration-tests/src/test/java/software/amazon/awssdk/v2migrationtests/MavenS3EventNotificationTest.java
user: login: davidh44
body: Is this separate module because of DateTime needing joda-time? If so, can we test most transforms in `maven` and the DateTime ones in `maven-nocompile`?
created_at: 2025-04-30T22:10:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+import org.joda.time.DateTime;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
path: test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-en/after/src/main/java/foo/bar/S3EventNotificationTest.java
user: login: dagnir
body: I really think we should investigate if we can do without too much effort. As is, the long, single line comments are difficult to read; if we're adding comments it's probably because it's re: something the customer should know about so we should make it easier for them to get that information.

Shouldn't we be able to use the indent information from the select (`select.getAfter().getIndent()`) to preserve the formatting?


This is arguably much easier to read for example
```java
        DateTime eventTime = /* AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. 
                                AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using
                                DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your 
                                project after migration.
                             */
                             new DateTime(record.getEventTime().toEpochMilli());
```
created_at: 2025-05-01T01:50:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+import org.joda.time.DateTime;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
path: test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-en/after/src/main/java/foo/bar/S3EventNotificationTest.java
user: login: Fred1155
body: Currently all added comments are like this. It might require some change the comments recipe, as well as all the integration test cases. We can address this problem in a separate PR.
created_at: 2025-05-01T16:29:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 foo.bar;
+
+import software.amazon.awssdk.eventnotifications.s3.model.S3Bucket;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;
+import software.amazon.awssdk.eventnotifications.s3.model.S3;
+import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord;
+import software.amazon.awssdk.eventnotifications.s3.model.S3Object;
+import software.amazon.awssdk.eventnotifications.s3.model.RequestParameters;
+import software.amazon.awssdk.eventnotifications.s3.model.ResponseElements;
+import software.amazon.awssdk.eventnotifications.s3.model.RestoreEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.UserIdentity;
+import software.amazon.awssdk.eventnotifications.s3.model.GlacierEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.LifecycleEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.IntelligentTieringEventData;
+import software.amazon.awssdk.eventnotifications.s3.model.ReplicationEventData;
+import org.joda.time.DateTime;
+
+public class S3EventNotificationTest {
+    public void parseEvent(String jsonInput) {
+        S3EventNotification notification = S3EventNotification.fromJson(jsonInput);
+
+        for (S3EventNotificationRecord record : notification.getRecords()) {
+            S3 s3 = record.getS3();
+
+            S3Bucket bucket = s3.getBucket();
+
+            S3Object object = s3.getObject();
+
+            String eventName = record.getEventName();
+
+            String eventNameEnum = record.getEventName();
+
+            DateTime eventTime = /*AWS SDK for Java v2 migration: getEventTime returns Instant instead of DateTime in v2. AWS SDK v2 does not include org.joda.time as a dependency. If you want to keep using DateTime, you'll need to manually add "org.joda.time:joda-time" dependency to your project after migration.*/new DateTime(record.getEventTime().toEpochMilli());
+
path: test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/maven-en/after/src/main/java/foo/bar/S3EventNotificationTest.java
user: login: dagnir
body: That's fine with me. Can we please create a backlog item?
created_at: 2025-05-01T19:50:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,54 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. 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.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.v2migrationtests;
+
+import static software.amazon.awssdk.v2migrationtests.TestUtils.replaceVersion;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIf;
+
+public class MavenS3EventNotificationTest extends MavenTestBase {
path: test/v2-migration-tests/src/test/java/software/amazon/awssdk/v2migrationtests/MavenS3EventNotificationTest.java
user: login: Fred1155
body: Yes. Will do that. 
created_at: 2025-05-01T19:55:01Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-01T21:18:47Z
body: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=aws_aws-sdk-java-v2&pullRequest=6059) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [7.4% Coverage on New Code](https://sonarcloud.io/component_measures?id=aws_aws-sdk-java-v2&pullRequest=6059&metric=new_coverage&view=list) (required ≥ 80%)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [18.9% Duplication on New Code](https://sonarcloud.io/component_measures?id=aws_aws-sdk-java-v2&pullRequest=6059&metric=new_duplicated_lines_density&view=list) (required ≤ 3%)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aws_aws-sdk-java-v2&pullRequest=6059)


author_association: NONE