본문 바로가기

AWS/Simple Notification Service(SNS)

2) Spring Boot로 AWS SNS publish 하기

반응형

앞에서 AWS SNS 설정에 대해 공부를 해봤다.

이제 springboot application 에서 SNS 보내는것에 대해 알아보자.

먼저 applicaton.properties에 아래 설정 추가.

cloud.aws.region.static=ap-northeast-2
cloud.aws.region.auto=false

위 설정에 대한 key 값을 설정을 위해 AWS AIM 설정에 들어가 

간단하게 snsPublish권한만 추가해준다. 그리고 나면 아래와 같이  access key와 시크릿키가 를 처음 application.properties에 넣어준다.

 

자 이제 aws clinet 설정을 해준다.

package com.devracoon.awssnstest;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.InstanceProfileCredentialsProvider;
import com.amazonaws.services.sns.AmazonSNSClient;
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class AwsConfiguration {
    @Value("${cloud.aws.credentials.access-key}")
    private String awsAccessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String awsSecretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Value("${spring.profiles.active:}")
    private String activeProfile;

    @Bean
    public AmazonSNSClient amazonSNSClient(Environment environment ) {
        if(StringUtils.equals(activeProfile , "")){
            return (AmazonSNSClient) AmazonSNSClientBuilder
                    .standard()
                    .withRegion(region)
                    .withCredentials(InstanceProfileCredentialsProvider.getInstance())
                    .build();
        }else{
            return (AmazonSNSClient) AmazonSNSClientBuilder
                    .standard()
                    .withRegion(region)
                    .withCredentials(new AWSStaticCredentialsProvider(
                            new BasicAWSCredentials(environment.getProperty("cloud.aws.credentials.access-key"), environment.getProperty("cloud.aws.credentials.secret-key"))))
                    .build();
        }

    }
}

 

위 aws sns client 생성 부분에서  activeProfile 을 체크 하는 부분이 있는 이유는 로컬 일때와 ec2 instance에서의 

aws access key를 읽어오는 부분이 달라지기 떄문이다. 

로컬일때는 springboot applicaton을 실행할때 enviroment에 속성값을 추가하는 방식이고 

ec2 인스턴스일떄는  아래 aws의 가이드에 나와 있는 방법으로 읽어 오는게 권장 방법이다.

https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html

 

Set up AWS Credentials and Region for Development - AWS SDK for Java

Set up AWS Credentials and Region for Development To connect to any of the supported services with the AWS SDK for Java, you must provide AWS credentials. The AWS SDKs and CLIs use provider chains to look for AWS credentials in a number of different places

docs.aws.amazon.com

이유는 보안적인 이유로 application.properties에 액세스키와 시크릿 키를 넣어도 되지만 키값이 소스코드에 들어가 있을경우 

외부에 노출 우려가 있기 때문이다.

 

package com.devracoon.awssnstest.service;

import com.amazonaws.services.sns.AmazonSNSClient;
import com.devracoon.awssnstest.dto.SnsMessage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.javafx.geom.transform.Identity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Slf4j
@Service
@RequiredArgsConstructor
public class AwsSnsService {

    public final static String TEST_SNS_ARN="arn:aws:sns:ap-northeast-2:385423560848:DevRacoon-SNS-Test";
    @Autowired
    private final AmazonSNSClient amazonSNSClient;

    @Autowired
    private ObjectMapper mapper;

    public void testSnsPublish() {

        SnsMessage snsMessage = SnsMessage.builder().messageId(UUID.randomUUID().toString())
                .messageText("test message")
                .eventTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")))
                .build();

        try{
            String message = mapper.writeValueAsString(snsMessage);
            amazonSNSClient.publish(TEST_SNS_ARN ,  message);

        }catch (Exception e){
            log.error("AWS SNS publish error" , e);
        }
    }

}

테스트를 위한 간단한 publish service를 만들어보았다. 해당 service를 통해 sns 발송하고 1부에 만들었던 SQS에서 수신이 잘되는지 확인해 보면 

 

와 같이 정상적으로 발신되는것을 확인 할 수 있습니다.

여기까지 간단한 sns 발송 테스트 이고 .  sns장애시 sns Publish 실패 재시도에 대한 failover에 대한 처리를 나중에 다시 

내용을 추가하도록 하자.

'AWS > Simple Notification Service(SNS)' 카테고리의 다른 글

3)SpringBoot SQSListner로 메세지 받기  (0) 2022.02.08
1) AWS SNS 설정하기  (0) 2021.11.29