Skip to content

Commit 7485d09

Browse files
authored
Merge pull request #533 from DSM-PICK/473-fcm-리펙토링
473 fcm 리펙토링
2 parents 8edbcee + 0cf1542 commit 7485d09

35 files changed

+386
-121
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ dependencies {
7979
implementation(Dependencies.SMTP)
8080

8181
implementation(Dependencies.GOOGLE_OAUTH)
82+
83+
implementation(Dependencies.KAFKA)
8284
}
8385

8486
tasks.withType<KotlinCompile> {
Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,35 @@
11
object Dependencies {
2-
// kotlin
32
const val KOTLIN_REFLECT = "org.jetbrains.kotlin:kotlin-reflect"
43
const val JACKSON = "com.fasterxml.jackson.module:jackson-module-kotlin:${DependencyVersions.JACKSON_VERSION}"
54
const val JACKSON_TYPE = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${DependencyVersions.JACKSON_VERSION}"
65

7-
// web
86
const val SPRING_WEB = "org.springframework.boot:spring-boot-starter-web"
97

108
const val REDIS = "org.springframework.boot:spring-boot-starter-data-redis:${DependencyVersions.REDIS_VERSION}"
119

12-
// database
1310
const val SPRING_DATA_JPA = "org.springframework.boot:spring-boot-starter-data-jpa:${PluginVersions.SPRING_BOOT_VERSION}"
1411
const val MYSQL_CONNECTOR = "mysql:mysql-connector-java:${DependencyVersions.MYSQL}"
1512
const val SPRING_REDIS = "org.springframework.boot:spring-boot-starter-data-redis:${PluginVersions.SPRING_BOOT_VERSION}"
1613

17-
// security
1814
const val SPRING_SECURITY = "org.springframework.boot:spring-boot-starter-security"
1915

20-
// test
2116
const val SPRING_TEST = "org.springframework.boot:spring-boot-starter-test:${PluginVersions.SPRING_BOOT_VERSION}"
2217

23-
// open feign
2418
const val OPEN_FEIGN = "org.springframework.cloud:spring-cloud-starter-openfeign:${DependencyVersions.OPEN_FEIGN_VERSION}"
2519

26-
// validation
2720
const val SPRING_VALIDATION = "org.springframework.boot:spring-boot-starter-validation"
2821

29-
// json
3022
const val JSON = "org.json:json:${DependencyVersions.JSON_VERSION}"
3123

32-
// Jwt
3324
const val JWT = "io.jsonwebtoken:jjwt:${DependencyVersions.JWT_VERSION}"
3425

35-
// cloud
3626
const val SPRING_CLOUD = "org.springframework.cloud:spring-cloud-dependencies:${DependencyVersions.SPRING_CLOUD_VERSION}"
3727

3828
const val SWAGGER = "org.springdoc:springdoc-openapi-ui:${DependencyVersions.SWAGGER_VERSION}"
3929

40-
// QueryDSL
4130
const val QUERYDSL = "com.querydsl:querydsl-jpa:${DependencyVersions.QUERYDSL}"
4231
const val QUERYDSL_PROCESSOR = "com.querydsl:querydsl-apt:${DependencyVersions.QUERYDSL}:jpa"
4332

44-
// apachePOI
4533
const val APACHE_POI = "org.apache.poi:poi:${DependencyVersions.APACHE_POI}"
4634
const val APACHE_POI_OOXML = "org.apache.poi:poi-ooxml:${DependencyVersions.APACHE_POI}"
4735

@@ -59,7 +47,7 @@ object Dependencies {
5947

6048
const val GOOGLE_OAUTH = "com.google.auth:google-auth-library-oauth2-http:${DependencyVersions.GOOGLE_OAUTH2}"
6149

62-
63-
//smtp
6450
const val SMTP = "org.springframework.boot:spring-boot-starter-mail"
51+
52+
const val KAFKA = "org.springframework.kafka:spring-kafka:${DependencyVersions.KAFKA}"
6553
}

buildSrc/src/main/kotlin/DependencyVersions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ object DependencyVersions {
1313
const val AWS = "1.12.281"
1414
const val FCM = "8.1.0"
1515
const val GOOGLE_OAUTH2 = "1.17.0"
16+
const val KAFKA = "2.9.13"
1617
}

src/main/kotlin/dsm/pick2024/domain/application/service/ApplicationService.kt

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import dsm.pick2024.domain.application.port.out.SaveApplicationPort
1111
import dsm.pick2024.domain.application.presentation.dto.request.ApplicationRequest
1212
import dsm.pick2024.domain.event.dto.UserInfoRequest
1313
import dsm.pick2024.domain.event.enums.EventTopic
14+
import dsm.pick2024.domain.fcm.dto.request.FcmRequest
1415
import dsm.pick2024.domain.fcm.port.out.FcmSendPort
16+
import dsm.pick2024.domain.outbox.domain.Outbox
17+
import dsm.pick2024.domain.outbox.enum.EventType
18+
import dsm.pick2024.domain.outbox.port.out.SaveOutboxPort
1519
import dsm.pick2024.domain.user.port.`in`.UserFacadeUseCase
1620
import org.springframework.context.ApplicationEventPublisher
1721
import org.springframework.stereotype.Service
@@ -26,7 +30,8 @@ class ApplicationService(
2630
private val userFacadeUseCase: UserFacadeUseCase,
2731
private val eventPublisher: ApplicationEventPublisher,
2832
private val fcmSendPort: FcmSendPort,
29-
private val adminFinderUseCase: AdminFinderUseCase
33+
private val adminFinderUseCase: AdminFinderUseCase,
34+
private val saveOutboxPort: SaveOutboxPort
3035
) : ApplicationUseCase {
3136

3237
@Transactional
@@ -52,18 +57,22 @@ class ApplicationService(
5257
applicationKind = ApplicationKind.APPLICATION
5358
)
5459
)
60+
5561
val deviceToken = adminFinderUseCase.findByGradeAndClassNumOrThrow(
5662
grade = user.grade,
5763
classNum = user.classNum
5864
).deviceToken
5965

60-
deviceToken?.let {
61-
fcmSendPort.send(
62-
deviceToken = it,
63-
title = "[PiCK] ${user.grade}학년 ${user.classNum}${user.num}${user.name} 학생이 외출을 신청했습니다.",
64-
body = "사유: ${request.reason}"
66+
saveOutboxPort.saveOutbox(
67+
Outbox(
68+
payload = FcmRequest(
69+
tokens = listOf(deviceToken),
70+
title = "[PiCK] ${user.grade}학년 ${user.classNum}${user.num}${user.name} 학생이 외출을 신청했습니다.",
71+
body = "사유: ${request.reason}"
72+
),
73+
eventType = EventType.NOTIFICATION
6574
)
66-
}
75+
)
6776

6877
eventPublisher.publishEvent(UserInfoRequest(EventTopic.HANDLE_EVENT, user.id))
6978
}

src/main/kotlin/dsm/pick2024/domain/application/service/ChangeApplicationStatusService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ChangeApplicationStatusService(
3131
userFacadeUseCase.getUserById(
3232
it.userId
3333
).deviceToken
34-
}.filter { it.isNotBlank() }
34+
}
3535

3636
if (request.status == Status.OK) {
3737
approvalProcessor.process(applications, admin.name, deviceTokens)

src/main/kotlin/dsm/pick2024/domain/application/service/processor/ApplicationApprovalProcessor.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import dsm.pick2024.domain.attendance.port.`in`.AttendanceFinderUseCase
1111
import dsm.pick2024.domain.attendance.port.out.SaveAttendancePort
1212
import dsm.pick2024.domain.event.dto.ChangeStatusRequest
1313
import dsm.pick2024.domain.event.enums.EventTopic
14-
import dsm.pick2024.domain.fcm.port.out.FcmSendPort
14+
import dsm.pick2024.domain.outbox.port.`in`.OutboxFacadeUseCase
1515
import org.springframework.context.ApplicationEventPublisher
1616
import org.springframework.stereotype.Service
17+
import org.springframework.transaction.annotation.Transactional
1718

1819
@Service
1920
class ApplicationApprovalProcessor(
@@ -23,9 +24,10 @@ class ApplicationApprovalProcessor(
2324
private val saveAttendancePort: SaveAttendancePort,
2425
private val attendanceService: AttendanceService,
2526
private val eventPublisher: ApplicationEventPublisher,
26-
sendMessageUseCase: FcmSendPort
27-
) : ApplicationStatusProcessor(sendMessageUseCase) {
27+
outboxFacadeUseCase: OutboxFacadeUseCase
28+
) : ApplicationStatusProcessor(outboxFacadeUseCase) {
2829

30+
@Transactional
2931
override fun process(applications: List<Application>, adminName: String, deviceTokens: List<String>) {
3032
val updateApplications = applications.map { it.copy(teacherName = adminName, status = Status.OK) }
3133

src/main/kotlin/dsm/pick2024/domain/application/service/processor/ApplicationRejectionProcessor.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ import dsm.pick2024.domain.application.domain.Application
44
import dsm.pick2024.domain.application.enums.ApplicationKind
55
import dsm.pick2024.domain.application.port.out.DeleteApplicationPort
66
import dsm.pick2024.domain.event.dto.ChangeStatusRequest
7-
import dsm.pick2024.domain.fcm.port.out.FcmSendPort
7+
import dsm.pick2024.domain.outbox.port.`in`.OutboxFacadeUseCase
88
import org.springframework.context.ApplicationEventPublisher
99
import org.springframework.stereotype.Service
10+
import org.springframework.transaction.annotation.Transactional
1011

1112
@Service
1213
class ApplicationRejectionProcessor(
1314
private val deleteApplicationPort: DeleteApplicationPort,
1415
private val eventPublisher: ApplicationEventPublisher,
15-
sendMessageUseCase: FcmSendPort
16-
) : ApplicationStatusProcessor(sendMessageUseCase) {
16+
private val outboxFacadeUseCase: OutboxFacadeUseCase
17+
) : ApplicationStatusProcessor(outboxFacadeUseCase) {
1718

19+
@Transactional
1820
override fun process(applications: List<Application>, adminName: String, deviceTokens: List<String>) {
1921
applications.forEach {
2022
deleteApplicationPort.deleteByIdAndApplicationKind(it.id!!, ApplicationKind.APPLICATION)
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package dsm.pick2024.domain.application.service.processor
22

33
import dsm.pick2024.domain.application.domain.Application
4-
import dsm.pick2024.domain.fcm.port.out.FcmSendPort
4+
import dsm.pick2024.domain.outbox.port.`in`.OutboxFacadeUseCase
55

66
abstract class ApplicationStatusProcessor(
7-
private val sendMessageUseCase: FcmSendPort
7+
private val outboxFacadeUseCase: OutboxFacadeUseCase
88
) {
99
abstract fun process(applications: List<Application>, adminName: String, deviceTokens: List<String>)
1010

11-
protected fun sendNotification(title: String, message: String, deviceTokens: List<String>) {
12-
sendMessageUseCase.sendAll(deviceTokens, title, message)
11+
protected fun sendNotification(title: String, message: String, deviceTokens: List<String?>) {
12+
outboxFacadeUseCase.sendNotificationAll(
13+
title = title,
14+
deviceToken = deviceTokens,
15+
body = message
16+
)
1317
}
1418
}

src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/CreateEarlyReturnService.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import dsm.pick2024.domain.earlyreturn.port.`in`.CreateEarlyReturnUseCase
1212
import dsm.pick2024.domain.earlyreturn.presentation.dto.request.CreateEarlyReturnRequest
1313
import dsm.pick2024.domain.event.dto.UserInfoRequest
1414
import dsm.pick2024.domain.fcm.port.out.FcmSendPort
15+
import dsm.pick2024.domain.outbox.port.`in`.OutboxFacadeUseCase
1516
import dsm.pick2024.domain.user.port.`in`.UserFacadeUseCase
1617
import org.springframework.context.ApplicationEventPublisher
1718
import org.springframework.stereotype.Service
@@ -26,7 +27,8 @@ class CreateEarlyReturnService(
2627
private val userFacadeUseCase: UserFacadeUseCase,
2728
private val eventPublisher: ApplicationEventPublisher,
2829
private val adminFinderUseCase: AdminFinderUseCase,
29-
private val fcmSendPort: FcmSendPort
30+
private val fcmSendPort: FcmSendPort,
31+
private val outboxFacadeUseCase: OutboxFacadeUseCase
3032
) : CreateEarlyReturnUseCase {
3133
@Transactional
3234
override fun createEarlyReturn(request: CreateEarlyReturnRequest) {
@@ -57,7 +59,7 @@ class CreateEarlyReturnService(
5759
).deviceToken
5860

5961
deviceToken?.let {
60-
fcmSendPort.send(
62+
outboxFacadeUseCase.sendNotification(
6163
deviceToken = it,
6264
title = "[PiCK] ${user.grade}학년 ${user.classNum}${user.num}${user.name} 학생이 조기귀가를 신청했습니다.",
6365
body = "사유: ${request.reason}"

src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/QueryAllOKEarlyReturnService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class QueryAllOKEarlyReturnService(
1818

1919
queryAllApplicationPort.findAllByApplicationKind(ApplicationKind.EARLY_RETURN)
2020
.filter { it.status == Status.OK }
21-
.map { it ->
21+
.map {
2222
QueryAllOKEarlyReturnResponse(it)
2323
}.distinctBy { it.id }.sortedWith(compareBy({ it.grade }, { it.classNum }, { it.num }))
2424
}

0 commit comments

Comments
 (0)