S3 이벤트 알림 작업 - AWS SDK for Java 2.x

S3 이벤트 알림 작업

버킷의 활동을 모니터링하는 데 도움이 되도록 Amazon S3는 특정 이벤트가 발생할 때 알림을 보낼 수 있습니다. Amazon S3 사용 설명서에서는 버킷이 보낼 수 있는 알림에 대한 정보를 얻을 수 있습니다.

SDK for Java를 사용하여 4개의 가능한 대상으로 이벤트를 보내도록 버킷을 설정할 수 있습니다.

  • Amazon Simple Notification Service(Amazon SNS) 주제

  • Amazon Simple Queue Service 대기열

  • AWS Lambda 함수

  • Amazon EventBridge

EventBridge로 이벤트를 전송하도록 버킷을 설정할 때 동일한 이벤트를 여러 대상으로 팬아웃하도록 EventBridge 규칙을 구성할 수 있습니다. 처음 3개 대상 중 하나로 직접 전송하도록 버킷을 구성하는 경우 각 이벤트에 하나의 대상 유형만 지정 가능합니다.

다음 섹션에서는 SDK for Java를 사용하여 Amazon SQS 대기열과 EventBridge라는 2가지 방법으로 S3 이벤트 알림을 전송하도록 버킷을 구성하는 방법을 알아봅니다.

마지막 섹션에서는 S3 이벤트 알림 API를 사용하여 객체 중심 방식으로 알림을 사용하는 방법을 보여줍니다.

대상으로 직접 전송하도록 버킷 구성

다음 예제에서는 객체 만들기 이벤트 또는 객체 태그 지정 이벤트가 버킷에서 발생할 때 알림을 보내도록 버킷을 구성합니다.

static void processS3Events(String bucketName, String queueArn) { // Configure the bucket to send Object Created and Object Tagging notifications to an existing SQS queue. s3Client.putBucketNotificationConfiguration(b -> b .notificationConfiguration(ncb -> ncb .queueConfigurations(qcb -> qcb .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING) .queueArn(queueArn))) .bucket(bucketName) ); }

위에 표시된 코드는 2가지 유형의 이벤트를 수신하도록 하나의 대기열을 설정합니다. 편리하게 queueConfigurations 메서드를 사용하면 필요한 경우 여러 대기열 대상을 설정할 수 있습니다. 또한 notificationConfiguration 메서드에서 하나 이상의 Amazon SNS 주제 또는 하나 이상의 Lambda 함수와 같은 추가 대상을 설정할 수 있습니다. 다음 코드 조각은 대기열 2개와 대상 유형 3개가 있는 예제를 보여줍니다.

s3Client.putBucketNotificationConfiguration(b -> b .notificationConfiguration(ncb -> ncb .queueConfigurations(qcb -> qcb .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING) .queueArn(queueArn), qcb2 -> qcb2.<...>) .topicConfigurations(tcb -> tcb.<...>) .lambdaFunctionConfigurations(lfcb -> lfcb.<...>)) .bucket(bucketName) );

코드 예제 GitHub 리포지토리에는 S3 이벤트 알림을 대기열로 직접 전송하는 전체 예제가 포함되어 있습니다.

EventBridge로 전송할 버킷 구성

다음 예시에서는 EventBridge에 알림을 보내도록 버킷을 구성합니다.

public static String setBucketNotificationToEventBridge(String bucketName) { // Enable bucket to emit S3 Event notifications to EventBridge. s3Client.putBucketNotificationConfiguration(b -> b .bucket(bucketName) .notificationConfiguration(b1 -> b1 .eventBridgeConfiguration(SdkBuilder::build)) .build());

EventBridge로 이벤트를 보내도록 버킷을 구성할 때 EventBridge가 디스패치할 이벤트 유형이나 최종 대상이 아닌 EventBridge 대상을 나타내기만 하면 됩니다. Java SDK의 EventBridge 클라이언트를 사용하여 최종 대상 및 이벤트 유형을 구성합니다.

다음 코드는 객체 만들기 이벤트를 주제 및 대기열로 팬아웃하도록 EventBridge를 구성하는 방법을 보여줍니다.

public static String configureEventBridge(String topicArn, String queueArn) { try { // Create an EventBridge rule to route Object Created notifications. PutRuleRequest putRuleRequest = PutRuleRequest.builder() .name(RULE_NAME) .eventPattern(""" { "source": ["aws.s3"], "detail-type": ["Object Created"], "detail": { "bucket": { "name": ["%s"] } } } """.formatted(bucketName)) .build(); // Add the rule to the default event bus. PutRuleResponse putRuleResponse = eventBridgeClient.putRule(putRuleRequest) .whenComplete((r, t) -> { if (t != null) { logger.error("Error creating event bus rule: " + t.getMessage(), t); throw new RuntimeException(t.getCause().getMessage(), t); } logger.info("Event bus rule creation request sent successfully. ARN is: {}", r.ruleArn()); }).join(); // Add the existing SNS topic and SQS queue as targets to the rule. eventBridgeClient.putTargets(b -> b .eventBusName("default") .rule(RULE_NAME) .targets(List.of ( Target.builder() .arn(queueArn) .id("Queue") .build(), Target.builder() .arn(topicArn) .id("Topic") .build()) ) ).join(); return putRuleResponse.ruleArn(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; }

Java 코드에서 EventBridge로 작업하려면 Maven pom.xml 파일에 eventbridge 아티팩트에 대한 종속성을 추가합니다.

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>eventbridge</artifactId> </dependency>

코드 예제 GitHub 리포지토리에는 S3 이벤트 알림을 EventBridge로 전송한 다음 주제 및 대기열로 전송하는 전체 예제가 포함되어 있습니다.

S3 이벤트 알림 API를 사용하여 이벤트 처리

대상이 S3 알림 이벤트를 수신한 후 S3 이벤트 알림 API를 사용하여 객체 중심 방식으로 이를 처리할 수 있습니다. S3 이벤트 알림 API를 사용하여 대상으로 직접 디스패치되는 이벤트 알림(첫 번째 예제 참조)을 사용할 수 있지만 EventBridge를 통해 라우팅되는 알림은 사용할 수 없습니다. 버킷에서 EventBridge로 전송된 S3 이벤트 알림에는 S3 이벤트 알림 API가 현재 처리하지 않는 다른 구조가 포함되어 있습니다.

종속성 추가

S3 이벤트 알림 API는 SDK for Java 2.x의 버전 2.25.11과 함께 릴리스되었습니다.

S3 이벤트 알림 API를 사용하려면 다음 코드 조각과 같이 Maven pom.xml에 필요한 종속성 요소를 추가합니다.

<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.X.X1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3-event-notifications</artifactId> </dependency> </dependencies>

1 최신 버전.

S3EventNotification 클래스 사용

JSON 문자열에서 S3EventNotification 인스턴스 만들기

JSON 문자열을 S3EventNotification 객체로 변환하려면 다음 예제와 같이 S3EventNotification 클래스의 정적 메서드를 사용합니다.

import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord import software.amazon.awssdk.services.sqs.model.Message; public class S3EventNotificationExample { ... void receiveMessage(Message message) { // Message received from SQSClient. String sqsEventBody = message.body(); S3EventNotification s3EventNotification = S3EventNotification.fromJson(sqsEventBody); // Use getRecords() to access all the records in the notification. List<S3EventNotificationRecord> records = s3EventNotification.getRecords(); S3EventNotificationRecord record = records.stream().findFirst(); // Use getters on the record to access individual attributes. String awsRegion = record.getAwsRegion(); String eventName = record.getEventName(); String eventSource = record.getEventSource(); } }

이 예제에서 fromJson 메서드는 JSON 문자열을 S3EventNotification 객체로 변환합니다. JSON 문자열에 누락된 필드가 있으면 해당 Java 객체 필드에 null 값이 표시되고 JSON의 추가 필드는 무시됩니다.

이벤트 알림 레코드에 대한 다른 API는 S3EventNotificationRecord에 대한 API 참조에서 확인할 수 있습니다.

S3EventNotification 인스턴스를 JSON 문자열로 변환

다음 예제와 같이 toJson(또는 toJsonPretty) 메서드를 사용하여 S3EventNotification 객체를 JSON 문자열로 변환합니다.

import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification public class S3EventNotificationExample { ... void toJsonString(S3EventNotification event) { String json = event.toJson(); String jsonPretty = event.toJsonPretty(); System.out.println("JSON: " + json); System.out.println("Pretty JSON: " + jsonPretty); } }

GlacierEventData, ReplicationEventData, IntelligentTieringEventData, LifecycleEventData에 대한 필드는 null인 경우 JSON에서 제외됩니다. 다른 null 필드는 null로 직렬화됩니다.

다음은 S3 객체 태그 지정 이벤트에 대한 toJsonPretty 메서드의 출력 예제입니다.

{ "Records" : [ { "eventVersion" : "2.3", "eventSource" : "aws:s3", "awsRegion" : "us-east-1", "eventTime" : "2024-07-19T20:09:18.551Z", "eventName" : "ObjectTagging:Put", "userIdentity" : { "principalId" : "AWS:XXXXXXXXXXX" }, "requestParameters" : { "sourceIPAddress" : "XXX.XX.XX.XX" }, "responseElements" : { "x-amz-request-id" : "XXXXXXXXXXXX", "x-amz-id-2" : "XXXXXXXXXXXXX" }, "s3" : { "s3SchemaVersion" : "1.0", "configurationId" : "XXXXXXXXXXXXX", "bucket" : { "name" : "amzn-s3-demo-bucket", "ownerIdentity" : { "principalId" : "XXXXXXXXXXX" }, "arn" : "arn:aws:s3:::XXXXXXXXXX" }, "object" : { "key" : "akey", "size" : null, "eTag" : "XXXXXXXXXX", "versionId" : null, "sequencer" : null } } } ] }

API를 사용하여 Amazon SQS 대기열에서 수신한 알림으로 작업하는 방법을 보여주는 전체 예제는 GitHub에서 사용할 수 있습니다.

Java 라이브러리를 사용하여 Lambda에서 S3 이벤트 처리: AWS SDK for Java 2.x 및 aws-lambda-java-events

SDK for Java 2.x를 사용하여 Lambda 함수에서 Amazon S3 이벤트 알림을 처리하는 대신 버전 3.x.x의 aws-lambda-java-events 라이브러리를 사용할 수 있습니다. AWS는 aws-lambda-java-events 라이브러리를 독립적으로 유지하며 자체 종속성 요구 사항을 보유하고 있습니다. aws-lambda-java-events 라이브러리는 Lambda 함수의 S3 이벤트에서만 작동하는 반면, SDK for Java 2.x는 Lambda 함수, Amazon SNS 및 Amazon SQS의 S3 이벤트에서 작동합니다.

두 접근 방식 모두 유사한 API를 사용하여 객체 중심 방식으로 JSON 이벤트 알림 페이로드를 모델링합니다. 다음 표에는 두 접근 방식을 사용하는 데 있어 주목할 만한 차이점이 나와 있습니다.

AWS SDK for Java aws-lambda-java-events 라이브러리
패키지 이름 지정

software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification

com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification
RequestHandler 파라미터

Lambda 함수의 RequestHandler 구현을 작성하여 JSON 문자열을 수신합니다.

import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification; public class Handler implements RequestHandler<String, String> { @Override public String handleRequest(String jsonS3Event, Context context) { S3EventNotification s3Event = S3EventNotification .fromJson(jsonS3Event); // Work with the s3Event object. ... } }
Lambda 함수의 RequestHandler 구현을 작성하여 S3Event 객체를 수신합니다.
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.S3Event; public class Handler implements RequestHandler<S3Event, String> { @Override public String handleRequest(S3Event s3event, Context context) { // Work with the s3Event object. ... } }
Maven 종속성
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.X.X</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3-event-notifications</artifactId> </dependency> <!-- Add other SDK dependencies that you need. --> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.X.X</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- The following two dependencies are for the aws-lambda-java-events library. --> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.15.0</version> </dependency> <!-- Add other SDK dependencies that you need. --> </dependencies>