Skip to content

Commit

Permalink
aws sns 서비스를 추가하라 (#52)
Browse files Browse the repository at this point in the history
aws sns 서비스를 추가하라
  • Loading branch information
truman-show committed Jun 12, 2021
2 parents da42a3b + 8981aca commit ad2f8c9
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 7 deletions.
2 changes: 1 addition & 1 deletion adapters/notification/adapter-aws-sns/build.gradle
Expand Up @@ -4,5 +4,5 @@ jar.enabled = true
dependencies {
implementation project(':common')
implementation project(':test-support')
implementation 'software.amazon.awssdk:sns'
implementation 'com.amazonaws:aws-java-sdk-sns'
}
@@ -0,0 +1,55 @@
package com.caregiver.config;


import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import com.amazonaws.services.sns.model.MessageAttributeValue;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
* AmazonSNS 객체를 생성합니다.
* 기본 자격 증명을 사용 합니다.
*/
@Configuration
@RequiredArgsConstructor
@SuppressWarnings("SpringFacetCodeInspection")
public class AwsDefaultCredential implements AwsSnsClientFactory {

private final AwsProperties awsProperties;

@Bean
@Override
public AmazonSNS createSnsClient() {
BasicAWSCredentials credentialsMaster = new BasicAWSCredentials(
awsProperties.getAccessKey(), awsProperties.getSecretKey());

AmazonSNSClientBuilder amazonSnsClientBuilder = AmazonSNSClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentialsMaster));
amazonSnsClientBuilder.setRegion(awsProperties.getSigningRegion());

return amazonSnsClientBuilder.build();
}

/**
* 메세지 전송 속성 값 을 가진 빈을 리턴합니다.
* <a href='https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sms_publish-to-phone.html#sms_publish_sdk'></a>
*/
@Bean
public Map<String, MessageAttributeValue> messageAttributeValue() {
return Map.of(
"AWS.SNS.SMS.SenderID",
new MessageAttributeValue().withStringValue("mySenderId").withDataType("String"),
"AWS.SNS.SMS.MaxPrice",
new MessageAttributeValue().withStringValue("0.50").withDataType("String"),
"AWS.SNS.SMS.SMSType",
new MessageAttributeValue().withStringValue("Promotional").withDataType("String"));
}

}
@@ -0,0 +1,26 @@
package com.caregiver.config;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* SNS 서비스를 사용하기위한 properties 클래스입니다.
*/
@Getter
@Component
public class AwsProperties {

@Value("${caregiver.aws.access-key:default-aws-access-key}")
private String accessKey;

@Value("${caregiver.aws.secret-key:default-aws-secret-key}")
private String secretKey;

@Value("${caregiver.aws.signing-region}")
private String signingRegion;

@Value("${caregiver.aws.sns.arn}")
private String arn;

}
@@ -0,0 +1,21 @@
package com.caregiver.config;


import com.amazonaws.services.sns.AmazonSNS;

/**
* <p> AWS SNS 를 사용하기 위한 객체를 생성합니다.</p>
* Spring profile 구분 별로 다른 자격 증명 방식을 사용하고 있습니다.
* 기본 자격 증명 방식 과 IAM ROLE 자격증명 방식을 사용합니다.
*
* @see <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html">
* Setting Credentials</a>
*/
public interface AwsSnsClientFactory {

/**
* SNS 서비스 클라이언트 AmazonSNS 리턴합니다.
*/
AmazonSNS createSnsClient();

}
Expand Up @@ -4,11 +4,8 @@ spring:

caregiver:
aws:
#service-endpoint:
signing-region: ap-northeast-2
signing-region: ap-northeast-1
access-key: ${caregiver.aws.secret-key}
secret-key: ${caregiver.aws.access-key}
sns:
arn: ${caregiver.aws.sns.arn}


@@ -0,0 +1,10 @@
package com.caregiver;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* SNS Application Junit Test를 실행하기 위한 클래스.
*/
@SpringBootApplication
public class AdapterSnsApplicationTest {
}
@@ -0,0 +1,20 @@
package com.caregiver.common;

import com.caregiver.config.AwsDefaultCredential;
import com.caregiver.config.AwsProperties;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

/**
* 테스트를 클래스에서 공통으로 필요로하는 정보를 관리하는 클래스.
*/
@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {AwsProperties.class, AwsDefaultCredential.class},
initializers = ConfigFileApplicationContextInitializer.class)
public class BaseConfiguration {

}
@@ -0,0 +1,29 @@
package com.caregiver.config;

import static org.assertj.core.api.Assertions.assertThat;

import com.amazonaws.regions.Regions;
import com.caregiver.common.BaseConfiguration;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

@SuppressWarnings("NonAsciiCharacters")
class AwsPropertiesTest extends BaseConfiguration {

@Autowired
AwsProperties awsProperties;

@Test
@DisplayName("Aws 설정정보를 확인하라")
public void Aws_설정정보를_확인하라() {

assertThat(awsProperties.getSigningRegion()).isEqualTo(Regions.AP_NORTHEAST_1.getName());
assertThat(awsProperties.getArn()).isNotBlank();
assertThat(awsProperties.getAccessKey()).isNotBlank();
assertThat(awsProperties.getSecretKey()).isNotBlank();

}


}
@@ -0,0 +1,53 @@
package com.caregiver.sms;

import static org.assertj.core.api.Assertions.assertThat;

import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.model.MessageAttributeValue;
import com.amazonaws.services.sns.model.PublishRequest;
import com.amazonaws.services.sns.model.PublishResult;
import com.caregiver.common.BaseConfiguration;
import com.caregiver.config.AwsDefaultCredential;
import java.util.Map;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

/**
* 문자메세지 발송 테스트.
*/
@SuppressWarnings({"NonAsciiCharacters", "CheckStyle"})
public class SendSmsMessageTest extends BaseConfiguration {

@Autowired
AwsDefaultCredential awsDefaultCredential;

/**
* 테스트가 실행될 경우 SMS 문자 메세지를 발송합니다.
* 과금이 발생 요소가 있기에 Disabled 처리합니다.
* TODO 테스트 코드 목킹 그리고 리팩토링
*/
@Test
@Disabled
@DisplayName("aws Sms 메일 발송을 테스트하라")
public void aws_sms_메일_발송을_테스트하라() {

final var amazonSns = awsDefaultCredential.createSnsClient();

final var publishResult = sendSmsMessage(amazonSns, "안녕하세요 이지훈입니다. 문자메세지 테스트",
"+8201093793259", awsDefaultCredential.messageAttributeValue());

assertThat(publishResult.getMessageId()).isNotBlank();
}

private PublishResult sendSmsMessage(AmazonSNS amazonSns, String message, String phoneNumber,
Map<String, MessageAttributeValue> smsAttributes) {

return amazonSns.publish(new PublishRequest().withMessage(message)
.withPhoneNumber(phoneNumber)
.withMessageAttributes(smsAttributes));

}

}
4 changes: 2 additions & 2 deletions build.gradle
Expand Up @@ -26,7 +26,7 @@ subprojects {
springBootVersion = "2.3.4.RELEASE"
mockitoVersion = "3.4.0"
lombokVersion = "1.18.12"
awsSdkVersion = "2.16.82"
awsSdkVersion = "1.12.5"
}

dependencies {
Expand Down Expand Up @@ -57,7 +57,7 @@ subprojects {
// 하위 모듈 내에서 이러한 종속성 중 하나가 필요한 경우 버전 번호가 dependencyManagement 클로저에서 로드되므로 버전 번호를 제공하지 않고 하위 모듈에서 지정할 수 있습니다.
// 이를 통해 Maven의 pom.xml 파일에있는 <dependencyManagement> 요소와 매우 유사하게 여러 모듈에 배포하는 대신 단일 위치에서 버전 번호를 지정할 수 있습니다.
mavenBom"org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
mavenBom"software.amazon.awssdk:bom:${awsSdkVersion}"
mavenBom"com.amazonaws:aws-java-sdk-bom:${awsSdkVersion}"
}
}

Expand Down

0 comments on commit ad2f8c9

Please sign in to comment.