Skip to content
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

Page test #506

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
run: chmod +x gradlew

- name: Generate Allure Results
run: ./gradlew test
run: ./gradlew generateAllureResults

- name: Load test report history
uses: actions/checkout@v3
Expand Down
5 changes: 5 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,9 @@ tasks.register("buildPinpointEcsDockerImagePrd") {
)
}
}
}

tasks.withType(Test::class.java) {
useJUnitPlatform()
systemProperty("allure.results.directory", "$projectDir/build/allure-results")
}
24 changes: 10 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,6 @@ subprojects {
includeCompileClasspath = false
}

tasks {
test {
useJUnitPlatform()
systemProperty("allure.results.directory", "$projectDir/build/allure-results")
}

register<Test>("architectureSpecTest") {
group = "spec"
useJUnitPlatform {
includeTags("ArchitectureSpec")
}
}
}

/** server url */
val serverUrl =
project.hasProperty("serverUrl").let {
Expand Down Expand Up @@ -265,4 +251,14 @@ tasks.named("gitExecutableHooks").configure {

tasks.named("clean").configure {
dependsOn("gitExecutableHooks")
}

tasks.withType(Test::class.java) {
useJUnitPlatform()
systemProperty("allure.results.directory", "$projectDir/build/allure-results")
}

tasks.register("generateAllureResults") {
dependsOn("api:test")
dependsOn("domain:crm:test")
}
15 changes: 15 additions & 0 deletions domain/crm/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation(project(":library:web"))
implementation(project(":library:email"))
implementation(project(":library:event"))
testImplementation(testFixtures(project(":library:event")))

/** jsoup - html parser */
implementation("org.jsoup:jsoup:1.15.3")
Expand All @@ -37,4 +38,18 @@ vaadin {

tasks.named("bootJar") {
dependsOn("vaadinBuildFrontend")
}

tasks.withType(Test::class.java) {
useJUnitPlatform()
systemProperty("allure.results.directory", "$projectDir/build/allure-results")

doLast {
val allureResults = File("$projectDir/build/allure-results")
val results = File("$rootDir/api/build/allure-results")
if (!results.exists()) {
results.mkdirs()
}
allureResults.copyRecursively(results, true)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package com.few.crm.email.domain

import com.few.crm.email.event.template.PostEmailTemplateEvent
import com.few.crm.support.jpa.converter.StringListConverter
import jakarta.persistence.*
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.domain.AbstractAggregateRoot
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.time.LocalDateTime

@Entity
@Table(name = "email_templates")
@EntityListeners(AuditingEntityListener::class)
data class EmailTemplate(
class EmailTemplate(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
Expand All @@ -27,7 +29,7 @@ data class EmailTemplate(
var version: Float = 1.0f,
@CreatedDate
var createdAt: LocalDateTime? = null,
) {
) : AbstractAggregateRoot<EmailTemplate>() {
protected constructor() : this(
templateName = "",
subject = "",
Expand All @@ -50,7 +52,15 @@ data class EmailTemplate(
)
}

fun isNewTemplate(): Boolean = id == null
fun isNewTemplate(): Boolean {
registerEvent(
PostEmailTemplateEvent(
templateId = this.id ?: 0,
eventType = "POST",
),
)
return id == null
}

fun modifySubject(subject: String?): EmailTemplate {
subject?.let {
Expand All @@ -77,6 +87,13 @@ data class EmailTemplate(
} ?: kotlin.run {
this.version += 0.1f
}

registerEvent(
PostEmailTemplateEvent(
templateId = this.id!!,
eventType = "POST",
),
)
return this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import jakarta.persistence.*
import org.springframework.data.jpa.domain.support.AuditingEntityListener

@Entity
@Table(name = "scheduled_events")
@Table(
name = "scheduled_events",
uniqueConstraints = [
UniqueConstraint(
name = "event_id_unique",
columnNames = ["event_id"],
),
],
)
@EntityListeners(AuditingEntityListener::class)
data class ScheduledEvent(
@Id
Expand Down
24 changes: 24 additions & 0 deletions domain/crm/src/main/kotlin/com/few/crm/email/domain/SentEmail.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.few.crm.email.domain

import com.few.crm.email.event.send.EmailSentEvent
import org.springframework.data.domain.AbstractAggregateRoot

class SentEmail(
private val userExternalId: String,
private val emailBody: String,
private val destination: String,
private val emailMessageId: String,
private val eventType: EmailSendEventType = EmailSendEventType.SEND,
) : AbstractAggregateRoot<SentEmail>() {
init {
registerEvent(
EmailSentEvent(
userExternalId = userExternalId,
emailBody = emailBody,
messageId = emailMessageId,
destination = destination,
eventType = eventType.name,
),
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.few.crm.email.event.schedule

import event.Event
import event.EventDetails
import event.EventUtils
import java.time.LocalDateTime

Expand All @@ -14,6 +15,7 @@ abstract class ScheduledEvent(
eventTime,
)

@EventDetails(publishedLocations = ["com.few.crm.support.schedule.TimeOutEventTaskManager"])
class CancelScheduledEvent(
val targetEventId: String,
eventId: String = EventUtils.generateEventId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ abstract class EmailSendEvent(
override fun toString(): String = "EmailSendEvent(messageId='$messageId', destination='$destination', timestamp=$timestamp)"
}

@EventDetails(outBox = false)
@EventDetails(
outBox = false,
publishedLocations = ["com.few.crm.email.domain.SentEmail", "com.few.crm.email.event.send.handler.NotificationEmailSendTimeOutInvokeEventHandler"],
)
class EmailSentEvent(
val userExternalId: String,
val emailBody: String,
Expand All @@ -59,6 +62,7 @@ class EmailSentEvent(
timestamp = timestamp,
)

@EventDetails(outBox = false, publishedLocations = ["com.few.crm.email.relay.send.EmailSendEventMessageMapper"])
class EmailDeliveryEvent(
eventId: String,
eventType: String,
Expand All @@ -75,6 +79,7 @@ class EmailDeliveryEvent(
timestamp = timestamp,
)

@EventDetails(outBox = false, publishedLocations = ["com.few.crm.email.relay.send.EmailSendEventMessageMapper"])
class EmailOpenEvent(
eventId: String,
eventType: String,
Expand All @@ -91,6 +96,7 @@ class EmailOpenEvent(
timestamp = timestamp,
)

@EventDetails(outBox = false, publishedLocations = ["com.few.crm.email.relay.send.EmailSendEventMessageMapper"])
class EmailClickEvent(
eventId: String,
eventType: String,
Expand All @@ -107,6 +113,7 @@ class EmailClickEvent(
timestamp = timestamp,
)

@EventDetails(outBox = false, publishedLocations = ["com.few.crm.email.relay.send.EmailSendEventMessageMapper"])
class EmailDeliveryDelayEvent(
eventId: String,
eventType: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.few.crm.email.event.send

import event.EventDetails
import event.EventUtils
import event.TimeExpiredEvent
import event.TimeOutEvent
import org.springframework.context.ApplicationEventPublisher
import java.time.LocalDateTime

@EventDetails(
publishedLocations = ["com.few.crm.email.event.send.replayer.NotificationEmailSendTimeOutEventReplayer", "com.few.crm.view.email.CrmEmailSendView"],
)
open class NotificationEmailSendTimeOutEvent(
val templateId: Long,
val userIds: List<Long>,
Expand Down Expand Up @@ -66,6 +70,9 @@ open class NotificationEmailSendTimeOutEvent(
)
}

@EventDetails(
publishedLocations = ["com.few.crm.email.event.send.NotificationEmailSendTimeOutInvokeEvent", "com.few.crm.email.relay.send.aws.ScheduledEventReverseRelay"],
)
class NotificationEmailSendTimeOutInvokeEvent(
val templateId: Long,
val userIds: List<Long>,
Expand All @@ -80,6 +87,7 @@ class NotificationEmailSendTimeOutInvokeEvent(
eventTime,
)

@EventDetails(publishedLocations = ["com.few.crm.email.event.send.NotificationEmailSendTimeOutEvent"])
class AwsNotificationEmailSendTimeOutEvent(
templateId: Long,
userIds: List<Long>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class NotificationEmailSendTimeOutInvokeEventHandler(
) : EventHandler<NotificationEmailSendTimeOutInvokeEvent> {
@CrmTransactional
override fun handle(event: NotificationEmailSendTimeOutInvokeEvent) {
scheduledEventRepository.findByEventId(event.timeOutEventId)?.complete()
scheduledEventRepository
.findByEventIdAndCompletedFalseForUpdate(event.timeOutEventId)
?.complete() ?: return
val templateId = event.templateId
val userIds = event.userIds
val template =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ class NotificationEmailSendTimeOutEventReplayer(
}

override fun replay() {
log.info { "==================== [START] NotificationEmailSendTimeOutEventReplayer ====================" }
val logBuffer = StringBuilder()
logBuffer.appendLine("NotificationEmailSendTimeOutEventReplayer:")
var expiredEventCount = 0L
var replayedEventCount = 0L
val expiredEventsLogBuffer =
StringBuilder().apply {
appendLine("\\-Expired events:")
}
val replayedEventsLogBuffer =
StringBuilder().apply {
appendLine("\\-Replayed events:")
}
eventScheduleRepository
.findAllByEventClassAndCompletedFalse(NotificationEmailSendTimeOutEvent::class.simpleName.toString())
.filter {
Expand All @@ -62,18 +71,20 @@ class NotificationEmailSendTimeOutEventReplayer(
)
if (event.isExpired()) {
// TODO alert
log.error { "Event is expired. eventId: ${event.eventId} expiredTime: ${event.expiredTime}" }
expiredEventsLogBuffer.appendLine(" - eventId: ${event.eventId} expiredTime: ${event.expiredTime}")
eventScheduleRepository.findByEventId(event.eventId)?.isNotConsumed()?.complete()
expiredEventCount++
return@forEach
}
log.info { "Event is replayed. eventId: ${event.eventId} expiredTime: ${event.expiredTime}" }
replayedEventsLogBuffer.appendLine(" - eventId: ${event.eventId} expiredTime: ${event.expiredTime}")
timeOutEventTaskManager.reSchedule(event)
replayedEventCount++
}
}
log.info { "Expired event count: $expiredEventCount" }
log.info { "Replayed event count: $replayedEventCount" }
log.info { "==================== [END] NotificationEmailSendTimeOutEventReplayer ====================" }
logBuffer.append(expiredEventsLogBuffer)
logBuffer.append(replayedEventsLogBuffer)
logBuffer.appendLine("Expired event count: $expiredEventCount")
logBuffer.append("Replayed event count: $replayedEventCount")
log.info { logBuffer.toString() }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.few.crm.email.event.template

import event.Event
import event.EventDetails
import event.EventUtils
import java.time.LocalDateTime

Expand All @@ -24,6 +25,7 @@ abstract class EmailTemplateTransactionAfterCompletionEvent(
eventTime = eventTime,
)

@EventDetails(publishedLocations = ["com.few.crm.email.domain.EmailTemplate"])
class PostEmailTemplateEvent(
val templateId: Long,
eventId: String = EventUtils.generateEventId(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.few.crm.email.repository

import com.few.crm.email.domain.ScheduledEvent
import jakarta.persistence.LockModeType
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Lock
import org.springframework.data.jpa.repository.Query

interface ScheduledEventRepository : JpaRepository<ScheduledEvent, Long> {
fun findByEventId(eventId: String): ScheduledEvent?

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT e FROM ScheduledEvent e WHERE e.eventId = :eventId AND e.completed = false")
fun findByEventIdAndCompletedFalseForUpdate(eventId: String): ScheduledEvent?

fun findAllByCompletedFalse(): List<ScheduledEvent>

fun findAllByEventClassAndCompletedFalse(eventClass: String): List<ScheduledEvent>
Expand Down
Loading
Loading