[Core] [Schedule] Add local schedule

This commit is contained in:
qianmoQ 2024-01-14 22:12:06 +08:00
parent ec27454a10
commit cf8ed7997d
15 changed files with 231 additions and 15 deletions

View File

@ -81,6 +81,7 @@
<module>parser/datacap-parser-trino</module>
<module>parser/datacap-parser-mysql</module>
<module>schedule/datacap-schedule-spi</module>
<module>schedule/datacap-schedule-local</module>
</modules>
<name>datacap</name>

View File

@ -0,0 +1,36 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap</artifactId>
<version>2024.01.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>datacap-schedule-local</artifactId>
<description>DataCap - Schedule for local</description>
<dependencies>
<dependency>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap-schedule-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package io.edurt.datacap.schedule.local
import io.edurt.datacap.schedule.Schedule
import io.edurt.datacap.schedule.ScheduleRequest
import io.edurt.datacap.schedule.ScheduleResponse
class LocalSchedule : Schedule {
override fun initialize(request: ScheduleRequest): ScheduleResponse {
return QuartzEndpoint.createJob(request)
}
override fun stop(request: ScheduleRequest): ScheduleResponse {
return QuartzEndpoint.removeJob(request)
}
}

View File

@ -0,0 +1,13 @@
package io.edurt.datacap.schedule.local
import com.google.inject.multibindings.Multibinder
import io.edurt.datacap.schedule.Schedule
import io.edurt.datacap.schedule.ScheduleModule
class LocalScheduleModule : ScheduleModule() {
override fun configure() {
Multibinder.newSetBinder(this.binder(), Schedule::class.java)
.addBinding()
.to(LocalSchedule::class.java)
}
}

View File

@ -0,0 +1,76 @@
package io.edurt.datacap.schedule.local
import io.edurt.datacap.schedule.ScheduleRequest
import io.edurt.datacap.schedule.ScheduleResponse
import org.quartz.*
import org.quartz.impl.StdSchedulerFactory
import org.slf4j.LoggerFactory
object QuartzEndpoint {
private val log = LoggerFactory.getLogger(this.javaClass)
private val scheduler: Scheduler = StdSchedulerFactory.getDefaultScheduler()
@JvmStatic
fun createJob(request: ScheduleRequest): ScheduleResponse {
val response = ScheduleResponse()
val name = getJobName(request)
val group = getJobGroup(request)
try {
val jobDetail: JobDetail = request.job?.let {
JobBuilder.newJob(it::class.java)
.withIdentity(name, group)
.build()
} ?: throw IllegalArgumentException("Job is null")
val trigger: Trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger-${request.name}", "trigger-group-${request.group}")
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(request.expression))
.build()
log.info("Add new job [ {} ] to group [ {} ]", name, group)
scheduler.scheduleJob(jobDetail, trigger)
if (! scheduler.isStarted) {
log.info("Scheduler starting")
scheduler.start()
}
response.successful = true
log.info("Add new job [ {} ] to group [ {} ] successful", name, group)
}
catch (ex: Exception) {
log.info("Add new job [ {} ] to group [ {} ] failure ", name, group, ex)
response.successful = false
response.message = ex.message
}
return response
}
@JvmStatic
fun removeJob(request: ScheduleRequest): ScheduleResponse {
val response = ScheduleResponse()
val name = getJobName(request)
val group = getJobGroup(request)
try {
log.info("Remove job [ {} ] from group [ {} ]", name, group)
scheduler.deleteJob(JobKey(name, group))
response.successful = true
log.info("Remove job [ {} ] from group [ {} ] successful", name, group)
}
catch (ex: Exception) {
log.info("Remove job [ {} ] from group [ {} ] failure ", name, group, ex)
response.successful = false
response.message = ex.message
}
return response
}
private fun getJobName(request: ScheduleRequest): String {
return "job-${request.name}"
}
private fun getJobGroup(request: ScheduleRequest): String {
return "job-group-${request.group}"
}
}

View File

@ -0,0 +1 @@
io.edurt.datacap.schedule.local.LocalScheduleModule

View File

@ -0,0 +1,10 @@
package io.edurt.datacap.schedule.local
import io.edurt.datacap.schedule.ScheduleJob
import org.quartz.JobExecutionContext
class ExampleJob : ScheduleJob() {
override fun execute(p0: JobExecutionContext?) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,27 @@
package io.edurt.datacap.schedule.local
import com.google.inject.Guice
import com.google.inject.Injector
import com.google.inject.Key
import com.google.inject.TypeLiteral
import io.edurt.datacap.schedule.Schedule
import org.junit.Before
import org.junit.Test
import kotlin.test.assertNotNull
class LocalScheduleModuleTest {
private val name = "Local"
private var injector: Injector? = null
@Before
fun before() {
injector = Guice.createInjector(LocalScheduleModule())
}
@Test
fun test() {
val schedule: Schedule? = injector?.getInstance(Key.get(object : TypeLiteral<Set<Schedule?>?>() {}))
?.first { v -> v?.name().equals(name) }
assertNotNull(schedule)
}
}

View File

@ -0,0 +1,31 @@
package io.edurt.datacap.schedule.local
import io.edurt.datacap.schedule.ScheduleRequest
import org.junit.Before
import org.junit.Test
import kotlin.test.assertTrue
class QuartzEndpointTest {
private val name: String = "TestJob"
private val group: String = "TestGroup"
private val request = ScheduleRequest()
@Before
fun before() {
request.name = name
request.group = group
request.expression = "*/10 * * * * ?"
request.job = ExampleJob()
}
@Test
fun testCreateJob() {
assertTrue(QuartzEndpoint.createJob(request).successful)
}
@Test
fun testRemoveJob() {
QuartzEndpoint.createJob(request)
assertTrue(QuartzEndpoint.removeJob(request).successful)
}
}

View File

@ -11,6 +11,10 @@
<artifactId>datacap-schedule-spi</artifactId>
<description>DataCap - Schedule spi</description>
<properties>
<quartz.version>2.3.2</quartz.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
@ -26,6 +30,11 @@
<artifactId>kotlin-reflect</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -9,7 +9,5 @@ interface Schedule {
fun initialize(request: ScheduleRequest): ScheduleResponse
fun start(request: ScheduleRequest): ScheduleResponse
fun stop(request: ScheduleRequest): ScheduleResponse
}

View File

@ -0,0 +1,5 @@
package io.edurt.datacap.schedule
import org.quartz.Job
abstract class ScheduleJob : Job

View File

@ -1,7 +1,7 @@
package io.edurt.datacap.schedule
class ScheduleRequest {
val name: String? = null
val expression: String? = null
val jobId: String? = null
}
data class ScheduleRequest(var name: String? = null,
var group: String = "DataCap-Schedule-Group",
var expression: String? = null,
var jobId: String? = null,
var job: ScheduleJob? = null)

View File

@ -1,6 +1,4 @@
package io.edurt.datacap.schedule
class ScheduleResponse {
val successful: Boolean = false
val message: String? = null
}
data class ScheduleResponse(var successful: Boolean = false,
var message: String? = null)

View File

@ -5,10 +5,6 @@ class TestSchedule : Schedule {
TODO("Not yet implemented")
}
override fun start(request: ScheduleRequest): ScheduleResponse {
TODO("Not yet implemented")
}
override fun stop(request: ScheduleRequest): ScheduleResponse {
TODO("Not yet implemented")
}