[Quartz] Admin Page

S_H_H·2022년 10월 27일
0

Quartz And Batch

목록 보기
7/8
QRTZ_ 테이블로 인해 Job에 대한 정보
Trigger에 대한 정보도 모두 확인이 가능하다

그렇다면 코드로 JobDetail, Trigger를 등록하지 않고
Admin Page를 만들어서 데이터를 관리해봐야겠다

분석

스케줄에 필요한 정보는 Job, Trigger가 있습니다.
Job과 Trigger를 등록 및 수정하기 위해, 기존 방식을 확인해보자

아래와 같이 설정하면 구동 시 QRTZ_테이블이 삭제되고 새롭게 생성된다
그와 동시에 Job, Trigger 정보도 들어가게되는데

spring:
  quartz:
    jdbc:
      initialize-schema: "always"

Job

    @Bean
    public JobDetail jobDetail() {
        //Set Job data map
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("jobName", "testJob");
		jobDataMap.put("jobLauncher", jobLauncher);
		jobDataMap.put("jobLocator", jobLocator);

        return JobBuilder.newJob(QuartzJob.class)
                .withIdentity("testJob", null)
                .setJobData(jobDataMap)
                .storeDurably()
                .build();
    }

그리고 아래 테이블을 조회해보면은

 SELECT * FROM QRTZ_JOB_DETAILS qjd ;

QRTZ_JOB_DETAILS

Data가 들어간걸 확인할 수 있다.

여기서 특이한 점은 JOB_DATA의 값이 이상하는 점


Trigger

Trigger도 Job과 동일하게 확인을 해보면은

    @Bean
    public Trigger trigger() {
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder
                .simpleSchedule()
                .withIntervalInSeconds(60)
                .repeatForever();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
        		.cronSchedule("0 * * * * ?");

        return TriggerBuilder
                .newTrigger()
                .forJob(jobOneDetail().getKey())
                .withIdentity("trigger", null)
                .withSchedule(scheduleBuilder)
                .build();
    }
SELECT * FROM QRTZ_TRIGGERS qt ;

QRTZ_TRIGGERS테이블은 Trigger Type과 상관없이 필수로 데이터가 있어야한다.
QRTZ_TRIGGERS

SELECT * FROM QRTZ_CRON_TRIGGERS qct ;

QRTZ_CRON_TRIGGERS테이블은 QRTZ_TRIGGERS-TRIGGER_TYPECRON인 경우 정보가 들어오게 된다
QRTZ_CRON_TRIGGERS

SELECT * FROM QRTZ_SIMPLE_TRIGGERS qst ;

QRTZ_CRON_TRIGGERS테이블은 QRTZ_TRIGGERS-TRIGGER_TYPESIMPLE인 경우 정보가 들어오게 된다
QRTZ_SIMPLE_TRIGGERS

QRTZ_TRIGGERS 테이블을 보면 다음 실행 시간, 이전 실행 시간, 시작 시간 컬럼이 있으며
기입된 시간 역시 일반적인 시간정보가 아니였다



CRUD 시작

Job 정보 기입

다른 컬럼에 대해서는 자신이 세팅한 값을 기입하면 되고 JOB_DATA 인 경우에는
값을 그대로 넣을 수 없었다.

컬럼 데이터 타입이 BLOB으로 되어있었기 때문에, 화면에서 문자로 기입 받은 내용을 변환하는 작업이 필요했다.

JOB_DATA는 전 Json 형식의 String으로 입력받았고,
String -> Object -> 직렬화 -> byte[]

String jobData = "{"jobName":"testJob"}";
byte[] blobJobData = null;				
				
JobDataMap jobDataMap = new JobDataMap();
ObjectMapper objectMapper = new ObjectMapper();
jobDataMap = objectMapper.readValue(jobData, jobDataMap.getClass());
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
	try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) {
		objectOutputStream.writeObject(jobDataMap);
		blobJobData = byteArrayOutputStream.toByteArray();
	}
}

위 과정을 거쳐 DB에 기입했고, 반대로 조회인 경우도 위 순서의 반대로 가져왔다.

Trigger 정보 기입

Trigger인 경우에는 _TIME 컬럼을 제외한 나머지 값은 그대로 기입하면 된다.
_TIME 컬럼인 경우 NUMBER(13,0) 데이터 타입을 사용하고 있었다.

해당 데이터 타입으로 변환을 할려면 Epoch로 변환을 해야한다.
String -> Date -> Long

CronExpression을 기입받아 CronSequenceGenerator를 사용했고,
Simple인 경우에는 MILLISECOND 입력받아
Date 값으로 변환했다.

LocalDateTime.parse(dataFormat.format(date), DateTimeFormatter.ofPattern(dateformat))
				.atZone(ZoneId.systemDefault())
				.toInstant()
				.toEpochMilli();

위 처럼 타입 변환 후 기입 처리, 반대로 read할때는 역순으로 진행

주의사항

Trigger 정보를 넣을 때
Cron이면 QRTZ_TRIGGERS -> QRTZ_CRON_TRIGGERS 순서로 INSERT 처리
반대로 삭제를 할때는 역순으로 삭제처리를 해야한다.

그리고 JOB_NAMEQRTZ_JOB_DETAILS 테이블에 있는 JOB_NAME을 기입해야한다

QRTZ_JOB_DETAILS 테이블 JOB_DATA를 보면 {"jobName":"testJob"} 들어가있다.
ADMIN PAGE에서 Job을 등록할때도 동일하게 넣어줘야 실행이된다.




이제 코드에서 JobBuilder, TriggerBuilder 를 사용하지 않고, 등록이 가능하다.

화면에서 Job, Trigger에 대한 정보를 한 눈에 확인할 수 있으니 편하다

필요시 Trigger를 등록하여 일회성으로 실행할 수 있다.

#[Quartz] Spring Batch Re-Schedule When Fail (JDBC) 게시물에서 에러로 인한 Trigger가 등록이 된경우에도 확인이 가능하니, 편리하다

JOB_DATA를 수정해 Job 실행 시 분기처리가 편리했다.

profile
LEVEL UP

0개의 댓글