• 티스토리 홈
  • 프로필사진
    알쓸개잡
  • 태그
  • 블로그 관리
  • 글 작성
알쓸개잡
  • 프로필사진
    알쓸개잡
    • 분류 전체보기 (98)
      • 스프링부트 (57)
      • AWS (5)
      • 쿠버네티스 (7)
      • 자바 (19)
      • 인프라 (1)
      • ETC (9)
  • 리얼포스 Realforce R3S 키보드 R3SD13 토프레 무점접키보드, 기본, 기본, 텐키리스
    반응형
# Home
# 공지사항
#
# 태그
# 검색결과
# 방명록
  • AWS MediaConvert SDK 사용 방법 (3) - SNS 연결하기
    2023년 08월 18일
    • 알쓸개잡
    • 작성자
    • 2023.08.18.:26

    AWS MediaConvert 주제의 마지막 포스팅 입니다. 지난 포스팅에서는 AWS MediaConvert 를 사용하기 위한 role 생성과 MediaConvert SDK 를 이용하여 Job 을 생성하는 방법을 알아 보았습니다.

    2023.08.17 - [AWS] - AWS MediaConvert SDK 사용 방법 (1) - role 생성하기

    2023.08.18 - [AWS] - AWS MediaConvert SDK 사용 방법 (2) - Job 생성 코드

    이번 포스팅에서는 AWS MediaConvert 와 SNS를 연동하여 MediaConvert Job 수행 완료 이벤트를 받는 방법에 대해서 설명합니다.

    AWS MediaConvert 모니터링에 대한 문서는 아래 링크에서 확인할 수 있습니다.

    https://docs.aws.amazon.com/mediaconvert/latest/ug/setting-up-cloudwatch-event-rules.html

     

    AWS SNS 로 부터 완료 메시지를 수신하기 위한 REST API 를 생성

    REST API 를 통해서 MediaConvert Job 완료 메시지를 수신할 것이기 때문에 REST API URL 이 먼저 있어야 합니다.

    package com.example.mediaconvert.controller;
    
    import com.example.mediaconvert.dto.MediaConvertSnsMessageDto;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import io.awspring.cloud.sns.annotation.endpoint.NotificationMessageMapping;
    import io.awspring.cloud.sns.annotation.endpoint.NotificationSubscriptionMapping;
    import io.awspring.cloud.sns.annotation.endpoint.NotificationUnsubscribeConfirmationMapping;
    import io.awspring.cloud.sns.annotation.handlers.NotificationMessage;
    import io.awspring.cloud.sns.annotation.handlers.NotificationSubject;
    import io.awspring.cloud.sns.handlers.NotificationStatus;
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping(path = "/media-convert/event")
    @Slf4j
    @RequiredArgsConstructor
    public class MediaConvertEventController {
    	//AWS SNS 구독 생성시에 확인 처리용 API 입니다.
    	//AWS SNS 구독 요청시 확인을 위해서 전송되는 subscribe url 을 호출합니다.
    	@NotificationSubscriptionMapping
    	public void handleSubscriptionMessage(NotificationStatus status) {
    		log.info("sns subscribe confirmation: {}", status);
    		status.confirmSubscription();
    	}
    
    	//AWS SNS 메시지를 수신하기 위한 API 입니다.
    	@NotificationMessageMapping
    	public void handleNotificationMessage(@NotificationSubject String subject,
                                              @NotificationMessage String message) 
                                              throws JsonProcessingException {
    		log.info("received sns message, subject={}, message={}", subject, message);
    		ObjectMapper objectMapper = new ObjectMapper();
    		//String JSON 메시지를 DTO 로 변환
    		MediaConvertSnsMessageDto mediaConvertSnsMessageDto = 
            	objectMapper.readValue(message, MediaConvertSnsMessageDto.class);
    		log.info("json object: {}", mediaConvertSnsMessageDto);
            
    		//DTO 를 기반으로 수신된 AWS SNS 메시지를 이용하여 후처리 작업을 진행합니다.
    	}
    }

    AWS SNS 메시지를 수신하기 위한 Controller 입니다.

    SNS 메시지를 수신하기 위한 endpoint 는 /media-convert/event 입니다.

    package global.voda.operator.dto;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonProperty;
    
    import java.util.List;
    import java.util.Map;
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record MediaConvertSnsMessageDto(@JsonProperty("version") String version,
                                            @JsonProperty("id") String id,
                                            @JsonProperty("detail-type") String detailType,
                                            @JsonProperty("source") String source,
                                            @JsonProperty("account") String account,
                                            @JsonProperty("time") String time,
                                            @JsonProperty("region") String region,
                                            @JsonProperty("resources") List<String> resources,
                                            @JsonProperty("detail") Detail detail,
                                            @JsonProperty("SigningCertURL") String signingCertURL,
                                            @JsonProperty("UnsubscribeURL") String unsubscribeURL) {
        @JsonIgnoreProperties(ignoreUnknown = true)
        public record Detail(@JsonProperty("timestamp") Long timestamp,
                             @JsonProperty("accountId") String accountId,
                             @JsonProperty("queue") String queue,
                             @JsonProperty("jobId") String jobId,
                             @JsonProperty("status") String status,
                             @JsonProperty("errorCode") Integer errorCode,
                             @JsonProperty("errorMessage") String errorMessage,
                             @JsonProperty("userMetadata") Map<String, String> userMetadata,
                             @JsonProperty("outputGroupDetails") List<OutputGroupDetail> outputGroupDetails,
                             @JsonProperty("paddingInserted") Integer paddingInserted,
                             @JsonProperty("blackVideoDetected") Integer blackVideoDetected) {
    
            @JsonIgnoreProperties(ignoreUnknown = true)
            public record OutputGroupDetail(@JsonProperty("outputDetails") List<OutputDetail> outputDetails,
                                            @JsonProperty("type") String type) {
    
                @JsonIgnoreProperties(ignoreUnknown = true)
                public record OutputDetail(@JsonProperty("outputFilePaths") List<String> outputFilePaths,
                                           @JsonProperty("durationInMs") Integer duration,
                                           @JsonProperty("videoDetails") VideoDetail videoDetail) {
                    @JsonIgnoreProperties(ignoreUnknown = true)
                    public record VideoDetail(@JsonProperty("widthInPx") Integer width,
                                              @JsonProperty("heightInPx") Integer height,
                                              @JsonProperty("averageBitrate") Integer averageBitrate) {
                    }
                }
            }
        }
    }

    수신된 SNS 메시지를 Deserialization 하기 위한 DTO 클래스 입니다.

     

     

    AWS SNS topic / subscription 생성

    첫번째로 MediaConvert 의 Job 완료 메시지를 수신하기 위해서는 우선 AWS SNS 토픽을 생성해야 합니다. 이때 생성하는 토픽 타입은 Standard 로 설정해야 합니다.

    SNS topic 생성

    생성된 MediaConvertJobCompleteErrorAlert 토픽 상세 페이지 하단에 [Create subscription] 을 통해서 subscription 을 생성합니다. 생성 전에 SNS 구독 생성 이벤트를 수신할 API 서버가 실행되고 있어야 합니다. 

    Create subscription > Details

    Enable raw message delivery 체크는 해제된 상태로 설정합니다.

    구독 생성시에 controller 의 handleSubscriptionMessage 가 호출되며 아래와 같은 로그가 생성되는 것을 확인할 수 있습니다.

     

     

    AWS EventBridge Rule 생성

    MediaConvert 의 Job 상태에 따라서 SNS 메시지를 전달 시키기 위해서 AWS EventBridge Rules 에 상태 정의를 해야합니다. 

    AWS EventBridge > Rules > Create rule 을 선택합니다. 

    Define rule detail
    Build event pattern > Event pattern

    Event pattern 섹션에서는 Specific state(s) 항목에 COMPLETE, ERROR 를 선택하여 MediaConvert Job 이 정상적으로 완료된 경우와 에러가 발생한 경우에 대해서만 SNS 이벤트를 발생시키도록 설정하였습니다.

    Select target(s)

    현재 생성하고 있는 EventBridge rule 을 SNS topic 에 연결합니다.

    Configure tags > Next 다음  Review and create 에서 설정 정보 확인 후 Create rule 을 선택하여 rule 을 생성합니다. 

     

    AWS SNS topic 과 EventBridge rules 연결 확인

    EventBridge rule 을 생성 후에 SNS topic 과 연결이 되었는지는 관리콘솔에서 AWS SNS > Topics > Access policy 탭에서 확인할 수 있습니다.

    {
      "Version": "2008-10-17",
      "Id": "__default_policy_ID",
      "Statement": [
        {
          "Sid": "__default_statement_ID",
          "Effect": "Allow",
          "Principal": {
            "AWS": "*"
          },
          "Action": [
            "SNS:GetTopicAttributes",
            "SNS:SetTopicAttributes",
            "SNS:AddPermission",
            "SNS:RemovePermission",
            "SNS:DeleteTopic",
            "SNS:Subscribe",
            "SNS:ListSubscriptionsByTopic",
            "SNS:Publish"
          ],
          "Resource": "<AWS SNS topic arn>",
          "Condition": {
            "StringEquals": {
              "AWS:SourceOwner": "<account ID>"
            }
          }
        },
        {
          "Sid": "<AWSEvents_MediaConvertJobStateCompleteError_Sid>",
          "Effect": "Allow",
          "Principal": {
            "Service": "events.amazonaws.com"
          },
          "Action": "sns:Publish",
          "Resource": "<AWS SNS topic arn>"
        }
      ]
    }

     

     

    MediaConvert Job Complete Event 수신 확인

    MediaConvert Job 을 생성 후 해당 Job 이 완료된 경우 SNS 이벤트를 수신하는 컨트롤러에는 아래와 같은 로그가 생성됨을 확인 할 수 있습니다.

    received sns message, subject=, message={
        "version": "0",
        "id": "<id>",
        "detail-type": "MediaConvert Job State Change",
        "source": "aws.mediaconvert",
        "account": "<account Id>",
        "time": "2023-08-18T10:13:51Z",
        "region": "<region>",
        "resources": [
            "<MediaConvert job arn>"
        ],
        "detail": {
            "timestamp": 1692353631573,
            "accountId": "<account Id>",
            "queue": "<queue Default>",
            "jobId": "<Job Id>",
            "status": "COMPLETE",
            "userMetadata": {},
            "outputGroupDetails": [
                {
                    "outputDetails": [
                        {
                            "outputFilePaths": [
                                "<S3 output object path>"
                            ],
                            "durationInMs": 15000,
                            "videoDetails": {
                                "widthInPx": 600,
                                "heightInPx": 120,
                                "averageBitrate": 36599,
                                "qvbrAvgQuality": 10,
                                "qvbrMinQuality": 10,
                                "qvbrMaxQuality": 10,
                                "qvbrMinQualityLocation": 0,
                                "qvbrMaxQualityLocation": 0
                            }
                        }
                    ],
                    "type": "FILE_GROUP"
                }
            ],
            "paddingInserted": 0,
            "blackVideoDetected": 0,
            "warnings": [
                {
                    "code": 230001,
                    "count": 1
                },
                {
                    "code": 230005,
                    "count": 1
                }
            ]
        }
    }

     

    3개의 포스팅에 걸쳐서 AWS MediaConvert SDK 를 사용하는 방법을 알아 보았습니다. 다뤄야 할 내용이 더 많지만 이 글을 읽으시는 분에게 도움이 되었기를 바랍니다.

    저작자표시 비영리 변경금지 (새창열림)

    'AWS' 카테고리의 다른 글

    bitbucket pipeline을 이용한 AWS ECS 애플리케이션 배포  (0) 2023.10.23
    AWS MediaConvert SDK 사용 방법 (2) - Job 생성 코드  (0) 2023.08.18
    AWS MediaConvert SDK 사용 방법 (1) - role 생성하기  (0) 2023.08.17
    AWS SES 사용하기  (0) 2023.07.31
    다음글
    다음 글이 없습니다.
    이전글
    이전 글이 없습니다.
    댓글
조회된 결과가 없습니다.
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바