From e72b75b73b7d92ff86bcffdc9b05679c423ee2fc Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:14:41 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20SQS=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dmforu-infrastructure/sqs/build.gradle.kts | 9 +++++++++ settings.gradle.kts | 1 + 2 files changed, 10 insertions(+) create mode 100644 dmforu-infrastructure/sqs/build.gradle.kts diff --git a/dmforu-infrastructure/sqs/build.gradle.kts b/dmforu-infrastructure/sqs/build.gradle.kts new file mode 100644 index 0000000..79719ae --- /dev/null +++ b/dmforu-infrastructure/sqs/build.gradle.kts @@ -0,0 +1,9 @@ +dependencies { + compileOnly(project(":dmforu-domain")) + + implementation(enforcedPlatform("software.amazon.awssdk:bom:2.21.20")) + implementation("software.amazon.awssdk:sqs") + + testImplementation(project(":dmforu-domain")) + testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0") +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 5c804bc..08752ba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,7 @@ include( "dmforu-domain", "dmforu-crawling", + "dmforu-infrastructure:sqs", "dmforu-infrastructure:fcm", "dmforu-infrastructure:storage:mysql", "dmforu-infrastructure:storage:mongo", From b2d81d5bc02b9a1f7d7805043ddca1c23c7a86c9 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:15:30 +0900 Subject: [PATCH 2/7] =?UTF-8?q?chore:=20SQS=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20.gitignore=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bc993a8..bd151f8 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ out/ ### Configuration Settings ### **/mongo.yml **/mysql.yml +**/sqs.yml **/fire-base-key.json \ No newline at end of file From aab544ccb2879b5399aa2b5b566fb23ed7ae6a08 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:16:31 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20AWS=20Config=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/com/dmforu/sqs/AWSConfig.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/AWSConfig.kt diff --git a/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/AWSConfig.kt b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/AWSConfig.kt new file mode 100644 index 0000000..407e6ef --- /dev/null +++ b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/AWSConfig.kt @@ -0,0 +1,39 @@ +package com.dmforu.sqs + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider +import software.amazon.awssdk.regions.Region +import software.amazon.awssdk.services.sqs.SqsAsyncClient + +@Configuration +class AWSConfig( + @Value("\${cloud.aws.credentials.access-key}") + val accessKey: String, + + @Value("\${cloud.aws.credentials.secret-key}") + val secretKey: String, + + @Value("\${cloud.aws.sqs.queue.url}") + val queueUrl: String, + + @Value("\${cloud.aws.sqs.queue.message-delay-seconds}") + val messageDelaySecs: Int, +) { + + @Bean + fun sqsAsyncClient(): SqsAsyncClient { + return SqsAsyncClient.builder() + .region(Region.AP_NORTHEAST_2) + .credentialsProvider(createAwsCredentialsProvider()) + .build() + } + + private fun createAwsCredentialsProvider(): StaticCredentialsProvider { + val basicAwsCredentials = AwsBasicCredentials.create(accessKey, secretKey) + + return StaticCredentialsProvider.create(basicAwsCredentials) + } +} \ No newline at end of file From a9866ead58a9168d8b6a0d68c0aee7ef399902b3 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:17:01 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20SQS=20=EB=A9=94=EC=84=B8=EC=A7=80?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/dmforu/sqs/SqsMessageMapper.kt | 32 +++++++++++++ .../com/dmforu/sqs/SqsMessageSendException.kt | 3 ++ .../kotlin/com/dmforu/sqs/SqsMessageSender.kt | 47 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageMapper.kt create mode 100644 dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSendException.kt create mode 100644 dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSender.kt diff --git a/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageMapper.kt b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageMapper.kt new file mode 100644 index 0000000..d89a05f --- /dev/null +++ b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageMapper.kt @@ -0,0 +1,32 @@ +package com.dmforu.sqs + +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue +import software.amazon.awssdk.services.sqs.model.SendMessageRequest + +object SqsMessageMapper { + + fun createRequest(content: String, attributes: Map, queueUrl: String, delaySeconds: Int): SendMessageRequest { + return SendMessageRequest.builder() + .queueUrl(queueUrl) + .delaySeconds(delaySeconds) + .messageAttributes(attributes) + .messageBody(content) + .build() + } + + fun createAttributes( + tokens: List, + title: String, + type: String, + url: String, + ): Map { + val attributes = mutableMapOf() + + attributes["tokens"] = MessageAttributeValue.builder().stringValue(tokens.toString()).dataType("String").build() + attributes["title"] = MessageAttributeValue.builder().stringValue(title).dataType("String").build() + attributes["type"] = MessageAttributeValue.builder().stringValue(type).dataType("String").build() + attributes["url"] = MessageAttributeValue.builder().stringValue(url).dataType("String").build() + + return attributes + } +} \ No newline at end of file diff --git a/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSendException.kt b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSendException.kt new file mode 100644 index 0000000..86d994e --- /dev/null +++ b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSendException.kt @@ -0,0 +1,3 @@ +package com.dmforu.sqs + +class SqsMessageSendException (message: String, cause: Throwable? = null) : RuntimeException(message, cause) \ No newline at end of file diff --git a/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSender.kt b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSender.kt new file mode 100644 index 0000000..18d0236 --- /dev/null +++ b/dmforu-infrastructure/sqs/src/main/kotlin/com/dmforu/sqs/SqsMessageSender.kt @@ -0,0 +1,47 @@ +package com.dmforu.sqs + +import com.dmforu.domain.message.MessageSender +import com.dmforu.domain.message.NoticeMessage +import com.dmforu.sqs.SqsMessageMapper.createAttributes +import com.dmforu.sqs.SqsMessageMapper.createRequest +import org.springframework.stereotype.Component +import software.amazon.awssdk.services.sqs.SqsAsyncClient +import software.amazon.awssdk.services.sqs.model.SendMessageResponse +import software.amazon.awssdk.services.sqs.model.SqsException + +@Component +class SqsMessageSender( + private val sqsAsyncClient: SqsAsyncClient, + private val awsConfig: AWSConfig, +) : MessageSender { + + override fun sendNoticeMessage(message: NoticeMessage, tokens: List) { + val attributes = createAttributes( + tokens = tokens, + title = message.title, + type = message.type, + url = message.url + ) + + val request = createRequest( + content = message.body, + attributes = attributes, + queueUrl = awsConfig.queueUrl, + delaySeconds = awsConfig.messageDelaySecs + ) + + try { + val future = sqsAsyncClient.sendMessage(request) + + future.whenComplete { sendMessageResponse: SendMessageResponse, throwable: Throwable? -> + if (throwable != null) { + throw SqsMessageSendException("[SQS Async Client] 메세지 전송에 실패하였습니다.", throwable) + } + } + } catch (sqsException: SqsException) { + throw SqsMessageSendException("[SQS] 메세지 전송에 실패하였습니다.", sqsException) + } + } + + +} \ No newline at end of file From 9b7bc5c9e4444f8b91d8ca73c9113e15c0f37021 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:18:35 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20FCM=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=EC=97=90=EC=84=9C=20SQS=20=EB=AA=A8=EB=93=88=EC=9D=84=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dmforu-admin/build.gradle.kts | 2 +- .../src/main/kotlin/com/dmforu/admin/AdminApplication.kt | 2 +- dmforu-admin/src/main/resources/application.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dmforu-admin/build.gradle.kts b/dmforu-admin/build.gradle.kts index c0dff20..c5578e8 100644 --- a/dmforu-admin/build.gradle.kts +++ b/dmforu-admin/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") - runtimeOnly(project(":dmforu-infrastructure:fcm")) + runtimeOnly(project(":dmforu-infrastructure:sqs")) runtimeOnly(project(":dmforu-infrastructure:storage:mysql")) runtimeOnly(project(":dmforu-infrastructure:storage:mongo")) diff --git a/dmforu-admin/src/main/kotlin/com/dmforu/admin/AdminApplication.kt b/dmforu-admin/src/main/kotlin/com/dmforu/admin/AdminApplication.kt index ca6d4be..10ecf15 100644 --- a/dmforu-admin/src/main/kotlin/com/dmforu/admin/AdminApplication.kt +++ b/dmforu-admin/src/main/kotlin/com/dmforu/admin/AdminApplication.kt @@ -8,7 +8,7 @@ import java.util.* @SpringBootApplication( scanBasePackages = [ "com.dmforu.admin", - "com.dmforu.fcm", + "com.dmforu.sqs", "com.dmforu.storage.db.mongo", "com.dmforu.storage.db.mysql" ] diff --git a/dmforu-admin/src/main/resources/application.yml b/dmforu-admin/src/main/resources/application.yml index ec5181b..8c832cb 100644 --- a/dmforu-admin/src/main/resources/application.yml +++ b/dmforu-admin/src/main/resources/application.yml @@ -7,6 +7,7 @@ spring: - mysql.yml - mongo.yml - monitoring.yml + - sqs.yml web.resources.add-mappings: false spring.lifecycle.timeout-per-shutdown-phase: 30s From 7ad9e51d756889262a6624fe257f7c02e382b5e3 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:43:55 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20CI=20=EC=84=A4=EC=A0=95=EC=97=90?= =?UTF-8?q?=20SQS=20yml=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e1f82f..1a254b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,12 @@ jobs: run: | mkdir -p ./dmforu-infrastructure/fcm/src/main/resources/key + - name: make sqs.yml + run: | + touch ./sqs.yml + echo "${{ secrets.SQS }}" | base64 --decode > ./sqs.yml + working-directory: ./dmforu-infrastructure/sqs/src/main/resources + - name: create JSON file run: | echo '{ From bc3695f19efb717b5704241d793e85fb94619338 Mon Sep 17 00:00:00 2001 From: GiJung <101462387+GiJungPark@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:50:31 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20SQS=20yml=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=9D=84=20=EC=A0=80=EC=9E=A5=ED=95=A0=20=EB=94=94=EB=9E=99?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a254b4..b22c143 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,9 +41,9 @@ jobs: echo "${{ secrets.MONGO }}" | base64 --decode > ./mongo.yml working-directory: ./dmforu-infrastructure/storage/mongo/src/main/resources - - name: Create Firebase key resources directory + - name: Create SQS resources directory run: | - mkdir -p ./dmforu-infrastructure/fcm/src/main/resources/key + mkdir -p ./dmforu-infrastructure/sqs/src/main/resources - name: make sqs.yml run: | @@ -51,6 +51,10 @@ jobs: echo "${{ secrets.SQS }}" | base64 --decode > ./sqs.yml working-directory: ./dmforu-infrastructure/sqs/src/main/resources + - name: Create Firebase key resources directory + run: | + mkdir -p ./dmforu-infrastructure/fcm/src/main/resources/key + - name: create JSON file run: | echo '{