Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class ChallengeStatusEndJobConfig(
private val jobRepository: JobRepository,
) {

@Bean(JOB_NAME)
@Bean(CHALLENGE_END_JOB_NAME)
fun job(): Job {
return JobBuilder(JOB_NAME, jobRepository)
return JobBuilder(CHALLENGE_END_JOB_NAME, jobRepository)
.start(step())
.build()
}
Expand Down Expand Up @@ -82,7 +82,7 @@ class ChallengeStatusEndJobConfig(
}

companion object {
const val JOB_NAME = "챌린지종료상태"
const val BEAN_PREFIX = JOB_NAME + "_"
const val CHALLENGE_END_JOB_NAME = "챌린지종료상태"
const val BEAN_PREFIX = CHALLENGE_END_JOB_NAME + "_"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.photi.server.config.batch.job

import com.photi.server.domain.user.Contact
import jakarta.persistence.EntityManagerFactory
import org.springframework.batch.core.Job
import org.springframework.batch.core.Step
import org.springframework.batch.core.configuration.annotation.JobScope
import org.springframework.batch.core.configuration.annotation.StepScope
import org.springframework.batch.core.job.builder.JobBuilder
import org.springframework.batch.core.repository.JobRepository
import org.springframework.batch.core.step.builder.StepBuilder
import org.springframework.batch.item.ItemProcessor
import org.springframework.batch.item.database.JpaItemWriter
import org.springframework.batch.item.database.JpaPagingItemReader
import org.springframework.batch.item.database.builder.JpaPagingItemReaderBuilder
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.transaction.PlatformTransactionManager
import java.time.LocalDate

@Configuration
class ContactReRegisterJobConfig(

@Value("\${spring.batch.chunk-size}")
private val chunkSize: Int,
private val entityManagerFactory: EntityManagerFactory,
private val transactionManager: PlatformTransactionManager,
private val jobRepository: JobRepository,
) {

@Bean(CONTACT_RE_REGISTER_JOB_NAME)
fun job(): Job {
return JobBuilder(CONTACT_RE_REGISTER_JOB_NAME, jobRepository)
.start(step())
.build()
}

@Bean(BEAN_PREFIX + "step")
@JobScope
fun step(): Step {
return StepBuilder(BEAN_PREFIX + "step", jobRepository)
.chunk<Contact, Contact>(chunkSize, transactionManager)
.reader(itemReader(null))
.processor(itemProcessor())
.writer(itemWriter())
.build()
}

@Bean(BEAN_PREFIX + "itemReader")
@StepScope
fun itemReader(@Value("#{jobParameters[date]}") date: LocalDate?): JpaPagingItemReader<Contact> {
val minusMonthDateTime = date?.minusMonths(MONTH_TO_SUBTRACT)?.atStartOfDay()
return JpaPagingItemReaderBuilder<Contact>()
.name(BEAN_PREFIX + "itemReader")
.entityManagerFactory(entityManagerFactory)
.pageSize(chunkSize)
.queryString(
"""
SELECT c FROM Contact c
WHERE c.isDeleted = true
AND c.deletedDate <= :date
ORDER BY c.id ASC
""".trimIndent()
)
.parameterValues(mapOf("date" to minusMonthDateTime))
.build()
}

@Bean(BEAN_PREFIX + "itemProcessor")
fun itemProcessor(): ItemProcessor<Contact, Contact> {
return ItemProcessor {
it.updateReRegisterStatus()
it
}
}

@Bean(BEAN_PREFIX + "itemWriter")
fun itemWriter(): JpaItemWriter<Contact> {
return JpaItemWriter<Contact>().apply {
setEntityManagerFactory(entityManagerFactory)
}
}

companion object {
const val CONTACT_RE_REGISTER_JOB_NAME = "회원재가입가능상태"
const val BEAN_PREFIX = CONTACT_RE_REGISTER_JOB_NAME + "_"
const val MONTH_TO_SUBTRACT = 1L
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.photi.server.config.batch.scheduler

import com.photi.server.config.batch.job.ChallengeStatusEndJobConfig.Companion.CHALLENGE_END_JOB_NAME
import com.photi.server.config.batch.job.ContactReRegisterJobConfig.Companion.CONTACT_RE_REGISTER_JOB_NAME
import org.springframework.batch.core.JobParametersBuilder
import org.springframework.batch.core.JobParametersInvalidException
import org.springframework.batch.core.configuration.JobRegistry
Expand All @@ -18,11 +20,20 @@ class JobScheduler(
private val jobRegistry: JobRegistry,
) {

@Scheduled(cron = "0 * 3 * * *")
fun runJob() {
@Scheduled(cron = "0 0 3 * * *")
fun runChallengeEndJob() {
runJob(CHALLENGE_END_JOB_NAME)
}

@Scheduled(cron = "0 0 4 * * *")
fun runContactReRegisterJob() {
runJob(CONTACT_RE_REGISTER_JOB_NAME)
}

fun runJob(jobName: String) {
val date = LocalDate.now().toString()
try {
val job = jobRegistry.getJob(JOB_NAME)
val job = jobRegistry.getJob(jobName)
val jobParameters = JobParametersBuilder()
.addString(JOB_PARAMETER, date)
.toJobParameters()
Expand All @@ -41,7 +52,6 @@ class JobScheduler(
}

companion object {
const val JOB_NAME = "챌린지종료상태"
const val JOB_PARAMETER = "date"
}
}
5 changes: 5 additions & 0 deletions src/main/kotlin/com/photi/server/domain/user/Contact.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ class Contact(
isDeleted = true
deletedDate = LocalDateTime.now()
}

fun updateReRegisterStatus() {
isDeleted = false
deletedDate = null
}
}