2016-12-28 2 views
2

Я работаю над проектом, в котором мы используем Spring Boot, Spring Batch и Camel.Идентификатор возвращаемого задания «немедленно» для весеннего пакетного задания до его завершения

Пакетный процесс запускается путем вызова конечной точки отдыха. Контроллер останова запускает маршрут верблюда, который запускает поток задания партии пружины (через компонент весеннего верблюда).

У меня нет контроля над внешним приложением, которое вызывает мое приложение. Мое приложение является частью более крупного ночного рабочего потока.

Выполнение пакетного задания может занять много времени, и поэтому внешнее приложение периодически проверяет мое пакетное задание через другую конечную точку отдыха, спрашивая, завершено ли задание. Он делает это путем опроса конечной точки останова состояния с идентификатором jobExecution, которому он хочет статус.

Для выполнения этого потока я внедрил контроллер отдыха, который запускает маршрут верблюда через ProducerTemplate. Моя проблема возвращает идентификатор выполнения задания сразу после запуска верблюжьего маршрута. Я не хочу, чтобы вызов остался до тех пор, пока работа не будет завершена, чтобы вернуться.

startJobViaRestCall ------> createBatchJob ----> runBatchJobUntilDone 
            | 
            | 
     Return jobExecutionData | 
<---------------------------------- 

Я пробовал использовать асинхронные звонки и фьючерсы, но не повезло. Я также попытался использовать прослушивание Camels безрезультатно. Проблема в том, что есть только события onComplete. Мне нужен крючок, который возвращается, как только работа была создана, но не запущена.

Например, следующий код ждет, пока пакетное задание не будет выполнено перед возвратом данных JobExecution, которые я хочу отправить назад (как json). Это имеет смысл, поскольку extractFutureBody будет ждать, пока ответ будет готов.

@RestController 
@Slf4j 
public class BatchJobController { 

    @Autowired 
    ProducerTemplate producerTemplate; 

    @RequestMapping(value = "/batch/job/start", method = RequestMethod.GET) 
    @ResponseBody 
    public String startBatchJob() { 
     log.info("BatchJob start called..."); 

     String jobExecution = producerTemplate.extractFutureBody(producerTemplate.asyncRequestBody(BatchRoute.ENDPOINT_JOB_START, ""), String.class); 

     return jobExecution; 
    } 

}  

Верблюд маршрут простой призыв к весенне-периодического компонента

public class BatchRoute<I, O> extends BaseRoute { 

    private static final String ROUTE_START_BATCH = "spring-batch:springBatchJob"; 

    @Override 
    public void configure() { 

     super.configure(); 
     from(ENDPOINT_JOB_START).to(ROUTE_START_BATCH); 

    } 
} 

Любые идеи о том, как я могу вернуть данные JobExecution как только она доступна?

ответ

0

Не знаете Как вы могли бы это сделать в Camel, но вот пример выполнения задания с использованием пружинного упора.

@RestController 
public class KpRest { 

    private static final Logger LOG = LoggerFactory.getLogger(KpRest.class); 
    private static String RUN_ID_KEY = "run.id"; 

    @Autowired 
    private JobLauncher launcher; 

    private final AtomicLong incrementer = new AtomicLong(); 


    @Autowired 
    private Job job; 


    @RequestMapping("/hello") 
    public String sayHello(){ 

     try { 
      JobParameters parameters = new JobParametersBuilder().addLong(RUN_ID_KEY, incrementer.incrementAndGet()).toJobParameters(); 
      JobExecution execution = launcher.run(job, parameters); 
      LOG.info("JobId {}, JobStatus {}", execution.getJobId(), execution.getStatus().getBatchStatus()); 
      return String.valueOf(execution.getJobId()); 
     } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException 
       | JobParametersInvalidException e) { 
      LOG.info("Job execution failed, {}", e); 
     } 
     return "Some Error"; 
    } 
} 

Вы можете сделать асинхронное задание, изменив JobLauncher.

@Bean 
    public JobLauncher simpleJobLauncher(JobRepository jobRepository){ 
     SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); 
     jobLauncher.setJobRepository(jobRepository); 
     jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor()); 
     return jobLauncher; 
    } 

Направить documentation для получения дополнительной информации

+0

Спасибо! «SimpleAsyncTaskExecutor» был ключом. Я определил пользовательский JobLauncher, который удаляет все параметры задания, добавленные компонентом Spring Batch Camel. Мне нужно было установить «TaskExecutor» в «SimpleAsyncTaskExecutor». Он по умолчанию был «SyncTaskExecutor», поскольку мой собственный JobLauncher расширил «SimpleJobLauncher». –

Смежные вопросы