Maven Dependency

Maven Dependency에 다음을 추가합니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

Quartz 설정 파일

Quartz 설정 파일을 src/main/resources/quartz.properties 로 생성합니다.

org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceIdGenerator.class=org.quartz.simpl.SimpleInstanceIdGenerator

# thread-pool
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=80
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true

# job-store
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
#org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
#org.quartz.jdbc.initialize-schema=always
#org.quartz.jobStore.tablePrefix=SCH_QRTZ_
#org.quartz.jobStore.isClustered=true
#org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.useProperties=true
#org.quartz.jobStore.dataSource=quartzDataSource
#org.quartz.dataSource.quartzDataSource.driver=org.postgresql.Driver
#org.quartz.dataSource.quartzDataSource.URL=jdbc:postgresql://localhost:5432/test
#org.quartz.dataSource.quartzDataSource.user=postgres
#org.quartz.dataSource.quartzDataSource.password=Clave:123
#org.quartz.dataSource.quartzDataSource.provider=hikaricp
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

# others
org.quartz.jobStore.misfireThreshold = 60000

Auto Configuration

application.yml 파일에 다음을 추가하여 Auto Configuration을 exclude 시킵니다.

autoconfigure:
  exclude:
    - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration

Quartz Job Scheduler 활성화

Quartz를 활성화 하기 위해서 다음과 같이 Spring Boot Configuration 클래스를 생성합니다.

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

@Configuration
@Slf4j
public class QuartzConfiguration {

    @Autowired
    ApplicationContext applicationContext;

    @Value("${app.metrics.impala-running-query.cron-expression}")
    String ImpalaCoordinatorRunningQueryJobCronExpression;

    @Bean
    public SchedulerFactoryBean scheduler() {
        SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
        schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties"));
        schedulerFactory.setJobFactory(springBeanJobFactory());

        // Job Detail
        JobDetail impalaCoordinatorRunningQueryJobDetail = impalaCoordinatorRunningQueryJobDetail();

        schedulerFactory.setJobDetails(impalaCoordinatorRunningQueryJobDetail);
        schedulerFactory.setTriggers(impalaCoordinatorRunningQueryJobDetailJobTrigger(impalaCoordinatorRunningQueryJobDetail));

        return schedulerFactory;
    }

    @Bean
    public SpringBeanJobFactory springBeanJobFactory() {
        AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    public JobDetail impalaCoordinatorRunningQueryJobDetail() {
        return JobBuilder.newJob().ofType(ImpalaCoordinatorRunningQueryJob.class)
                .storeDurably(true)
                .withIdentity("impala-coordinator-running-query-job")
                .withDescription("Impala Coordinator Running Query Job")
                .build();
    }

    public Trigger impalaCoordinatorRunningQueryJobDetailJobTrigger(JobDetail job) {
        return TriggerBuilder.newTrigger().forJob(job)
                .withIdentity("impala-coordinator-running-query-job-trigger")
                .withDescription("Impala Coordinator Running Query Job Trigger")
                .withSchedule(CronScheduleBuilder.cronSchedule(ImpalaCoordinatorRunningQueryJobCronExpression))
                .build();
    }
}

Quartz Job의 Autowire

Quartz Job에 Autowire 기능을 활성화 하기 위해서 다음의 클래스를 추가합니다.

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        beanFactory = applicationContext.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }

}

Quartz Job

이제 Quartz Job을 추가합니다.

import java.util.Map;

public class ImpalaCoordinatorRunningQueryJob implements Job {

    public static final org.slf4j.Logger coordinatorLogger = org.slf4j.LoggerFactory.getLogger("coordinatorLogger");

    @Value("${app.metrics.impala-running-query.tquery}")
    String tquery;

    @Value("${app.cloudera.manager-url}")
    String clouderaManagerUrl;

    @Value("${app.cloudera.manager-username}")
    String clouderaManagerUsername;

    @Value("${app.cloudera.manager-password}")
    String clouderaManagerPassword;

    @Autowired
    RestTemplate restTemplate;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "application/json");
        HttpEntity request = new HttpEntity(headers);

        ResponseEntity<Map> response = restTemplate.exchange(
                String.format("{}/api/v43/timeseries", clouderaManagerUrl),
                HttpMethod.GET,
                request,
                Map.class
        );

    }

}



  • 레이블 없음