스케줄러 를 이용한 배치

기본 개념 
 1. 스케줄러 : 일정한 시간 또는 시각에 특정 로직을 실행 
 2. 배치 : 실시간이 아닌 데이터의 일괄처리 
 
 SpringBoot에서 Quartz를 이용 
 1. dependencies 에 Quartz 추가 
 implementation 'org.springframework.boot:spring-boot-starter-quartz'
 
 2. Application Class에 스케줄링 
 @SpringBootApplication
@EnableScheduling // <------ 추가
public class CtsApiJavaApplication {
	public static final String APPLICATION_LOCATIONS = "spring.config.location="
		+ "classpath:environment.yml,"
		+ "classpath:application.yml";

	public static void main(String[] args) {
		new SpringApplicationBuilder(CtsApiJavaApplication.class)
			.properties(APPLICATION_LOCATIONS)
			.run(args);
	}

}
 
 3. Job 작성 
 package io.swit.api.schedule.job;

import io.swit.api.service.com.LogService;
import io.swit.api.service.eai.SyncService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Map;

@Slf4j
@AllArgsConstructor
public class SyncScheduleJob implements Job { // <------ Job implements
 private SyncService syncService;
 private LogService logService;

 @Override
 public void execute(JobExecutionContext context) throws JobExecutionException { // <------ execute 메서드에 수행업무 작성
 //조직 및 구성원 동기화
 try {
 log.info("조직 및 구성원 동기화 시작");
 Map<String,Integer> result = syncService.syncSwitTeams();
 log.info(String.format("%d조직 및 %d구성원 동기화 성공",result.get("team"),result.get("teamUser")));
 } catch (Exception e) {
 log.error("조직 및 구성원 동기화 실패 : " + e.getMessage());
 try {
 logService.saveErrorLog(e, "TeamBatch");
 } catch (Exception ex) {
 throw new RuntimeException(ex);
 }
 } finally {
 log.info("조직 및 구성원 동기화 종료");
 }

 //유저정보 동기화
 try{
 log.info("유저 및 팀 유저 동기화 시작");
 Map<String,Integer> result = syncService.syncSwitUsers();
 log.info(String.format("%d명 유저 및 %d명 팀 유저 동기화 성공",result.get("user"),result.get("teamUser")));
 }catch(Exception e){
 log.error("유저 및 팀 유저 동기화 실패 : " + e.getMessage());
 try {
 logService.saveErrorLog(e, "UserBatch");
 } catch (Exception ex) {
 throw new RuntimeException(ex);
 }
 }finally {
 log.info("유저 및 팀 유저 동기화 종료");
 }
 }
}

 
 4. Schedule 작성 
 package io.swit.api.schedule.config;

import io.swit.api.schedule.job.SyncScheduleJob;
import lombok.RequiredArgsConstructor;
import org.quartz.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.annotation.PostConstruct;
import java.util.TimeZone;

@Configuration
@RequiredArgsConstructor
public class SyncSchedule {
 private final SchedulerFactoryBean schedulerFactoryBean; // <------ 스케줄러빈 사용

 @PostConstruct
 public void scheduled() throws SchedulerException {
 JobDetail syncProvosioningJob = jobDetail("syncTeamUser", "Provisioning");
 CronTrigger syncProvisioningTrigger = trigger("scheduleTrigger", "trigger-group", "0 0 0/1 1/1 * ? *");
 this.schedulerFactoryBean.getScheduler().scheduleJob(syncProvosioningJob, syncProvisioningTrigger);
 }
 private JobDetail jobDetail(String name, String group){ // <------ 작성해놓은 Job class 로 JobDeail 생성
 JobDetail job = JobBuilder.newJob(SyncScheduleJob.class)
 .build();
 return job;
 }

 private CronTrigger trigger(String name, String group, String cronExpression) { // <------ 트리거 생성 ( 작성자는 크론표현식을 사용하여 크론 트리거 생성 )

 CronTrigger trigger = TriggerBuilder.newTrigger()
 .startNow()
 .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone("Asia/Seoul")))
 .build();
 return trigger;
 }
}