-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat/#7] ApiGatewayHandler 구현 #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
538f012
8323f67
3a16f11
5298b81
46ab2e7
4f8a3ef
e8d4aae
8384d59
2ae5631
8a6563a
be09093
1f629b6
baf67c2
deb22af
2504a92
1461ae9
7e9e109
09cee50
4593796
75b9e44
97bd0e7
a46e638
29568fe
e68e22d
40547b5
303c72f
4a52d91
976862e
8dc2eb2
0327c5b
953518d
5566389
75ffea2
770d86e
d298340
773c2d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.sopt.push.common; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class DeviceTokenException extends RuntimeException { | ||
|
|
||
| private final ErrorMessage errorMessage; | ||
|
|
||
| public DeviceTokenException(ErrorMessage errorMessage) { | ||
| super(errorMessage.getMessage()); | ||
| this.errorMessage = errorMessage; | ||
| } | ||
|
|
||
| public DeviceTokenException(ErrorMessage errorMessage, String detail) { | ||
| super(errorMessage.getMessage() + ": " + detail); | ||
| this.errorMessage = errorMessage; | ||
| } | ||
|
|
||
| public DeviceTokenException(ErrorMessage errorMessage, String detail, Throwable cause) { | ||
| super(errorMessage.getMessage() + ": " + detail, cause); | ||
| this.errorMessage = errorMessage; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.sopt.push.common; | ||
|
|
||
| public class PushFailException extends RuntimeException { | ||
|
|
||
| public PushFailException(String message, Throwable cause) { | ||
| super(message, cause); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| package com.sopt.push.config; | ||
|
|
||
| import com.sopt.push.common.DeviceTokenException; | ||
| import com.sopt.push.common.ErrorMessage; | ||
| import com.sopt.push.enums.Platform; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import software.amazon.awssdk.services.sns.SnsClient; | ||
| import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointRequest; | ||
| import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointResponse; | ||
| import software.amazon.awssdk.services.sns.model.SubscribeRequest; | ||
| import software.amazon.awssdk.services.sns.model.SubscribeResponse; | ||
|
|
||
| @Slf4j | ||
| public class SnsFactory { | ||
|
|
||
| private final SnsClient snsClient; | ||
| private final String allTopicArn; | ||
| private static final String PLATFORM_APPLICATION_IOS_ENV = "PLATFORM_APPLICATION_iOS"; | ||
| private static final String PLATFORM_APPLICATION_ANDROID_ENV = "PLATFORM_APPLICATION_ANDROID"; | ||
|
|
||
| public SnsFactory(SnsClient snsClient, EnvConfig envConfig) { | ||
| this.snsClient = snsClient; | ||
| this.allTopicArn = envConfig.getAllTopicArn(); | ||
| } | ||
|
|
||
| public SubscribeResponse subscribe(String endpointArn) { | ||
| SubscribeRequest request = | ||
| SubscribeRequest.builder() | ||
| .protocol("application") | ||
| .endpoint(endpointArn) | ||
| .topicArn(allTopicArn) | ||
| .build(); | ||
|
|
||
| return snsClient.subscribe(request); | ||
| } | ||
|
||
|
|
||
| public CreatePlatformEndpointResponse registerEndPoint( | ||
| String deviceToken, Platform platform, String userId) { | ||
| String platformApplicationArn = getPlatformApplicationArn(platform); | ||
|
|
||
| CreatePlatformEndpointRequest.Builder requestBuilder = | ||
| CreatePlatformEndpointRequest.builder() | ||
| .platformApplicationArn(platformApplicationArn) | ||
| .token(deviceToken); | ||
|
|
||
| if (userId != null && !userId.isBlank()) { | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| requestBuilder.customUserData(userId); | ||
| } | ||
|
|
||
| CreatePlatformEndpointRequest request = requestBuilder.build(); | ||
| return snsClient.createPlatformEndpoint(request); | ||
| } | ||
|
|
||
| private String getPlatformApplicationArn(Platform platform) { | ||
| String envVar = | ||
| platform == Platform.IOS ? PLATFORM_APPLICATION_IOS_ENV : PLATFORM_APPLICATION_ANDROID_ENV; | ||
| String value = System.getenv(envVar); | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (value == null || value.isBlank()) { | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| throw new DeviceTokenException( | ||
| ErrorMessage.PLATFORM_APP_ARN_NOT_SET, "Platform application ARN not set: " + envVar); | ||
| } | ||
| return value; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public record ApiGatewayRequestDto(RegisterHeaderDto header, Map<String, Object> body) {} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요기 Body는 Map으로 꼭 써야하나요? 요부분 제가 잘 몰라서..ㅎㅎ
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extractRequest에서 아래 액션을 확인하기 전에 body를 파싱하는데, 어떤 타입으로 변환할지 알 수가 없어서 Map<String, Object>로 받아서, 각 핸들러(handleRegister, handleCancel 등)에서 필요한 타입으로 mapper.convertValue()를 사용해서 변환하고 있습니다 !! switch (action) {
case REGISTER -> handleRegister(request);
case CANCEL -> handleCancel(request);
case SEND -> handleSend(request);
case SEND_ALL -> handleSendAll(request);
default -> throw new BusinessException(ErrorMessage.INVALID_REQUEST);
} |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import java.util.Set; | ||
|
|
||
| public record DeleteTokenDto(String deviceToken, Set<String> userIds) {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import com.sopt.push.enums.Actions; | ||
| import com.sopt.push.enums.Category; | ||
| import com.sopt.push.enums.NotificationStatus; | ||
| import com.sopt.push.enums.NotificationType; | ||
| import com.sopt.push.enums.Platform; | ||
| import com.sopt.push.enums.Services; | ||
| import java.util.Set; | ||
|
|
||
| public record LogCreateRequestDto( | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| String transactionId, | ||
| String entity, | ||
| String title, | ||
| String content, | ||
| String deviceToken, | ||
| String webLink, | ||
| String applink, | ||
| NotificationType notificationType, | ||
| Services orderServiceName, | ||
| NotificationStatus status, | ||
| Actions action, | ||
| Platform platform, | ||
| Category category, | ||
| String errorCode, | ||
| String errorMessage, | ||
| Set<String> userIds, | ||
| Set<String> messageIds, | ||
| String id) { | ||
| private static final String NULL = "NULL"; | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| private static String nvl(String v) { | ||
| return (v == null || v.isBlank()) ? NULL : v; | ||
| } | ||
|
|
||
| private static Set<String> normalizeSet(Set<String> s) { | ||
| return (s == null || s.isEmpty()) ? Set.of(NULL) : s; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import com.sopt.push.enums.Actions; | ||
| import com.sopt.push.enums.Platform; | ||
| import com.sopt.push.enums.Services; | ||
|
|
||
| public record RegisterHeaderDto( | ||
| String transactionId, Services service, Platform platform, Actions action) { | ||
|
|
||
| public RegisterHeaderDto { | ||
| if ((action == Actions.REGISTER || action == Actions.CANCEL) && platform == null) { | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| throw new IllegalArgumentException("Platform is required for REGISTER and CANCEL actions"); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import java.util.Set; | ||
|
|
||
| public record RegisterUserDto(String deviceToken, Set<String> userIds) {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import com.sopt.push.enums.Category; | ||
|
|
||
| public record SendAllPushDto( | ||
|
||
| String title, String content, Category category, String deepLink, String webLink) {} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.sopt.push.dto; | ||
|
|
||
| import com.sopt.push.enums.Category; | ||
| import java.util.Set; | ||
|
|
||
| public record SendPushDto( | ||
JungYoonShin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Set<String> userIds, | ||
| String title, | ||
| String content, | ||
| Category category, | ||
| String deepLink, | ||
| String webLink) {} | ||
Uh oh!
There was an error while loading. Please reload this page.