/* * Copyright (c) 2016 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.samples.wildfly.schedule.timer; import java.util.Date; import java.util.Properties; import java.util.concurrent.TimeUnit; import javax.batch.runtime.BatchStatus; import javax.ejb.ScheduleExpression; import org.jberet.rest.client.BatchClient; import org.jberet.samples.wildfly.common.BatchTestBase; import org.jberet.schedule.JobSchedule; import org.jberet.schedule.JobScheduleConfig; import org.jberet.schedule.JobScheduleConfigBuilder; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests for batch job scheduling in Java EE, JBoss EAP and WildFly environment, * where the job scheduler impl {@link org.jberet.schedule.TimerSchedulerBean} will be used. * <p> * A similar set of tests using {@link org.jberet.schedule.ExecutorSchedulerImpl} are in * wildfly-jberet-samples/scheduleExecutor/src/test/java/org/jberet/samples/wildfly/schedule/executor/ScheduleExecutorIT.java * <p> * A similar set of tests for Java SE environment are in * jberet-schedule/jberet-schedule-executor/src/test/java/org/jberet/schedule/ExecutorSchedulerIT.java */ public final class ScheduleTimerIT extends BatchTestBase { /** * The job name defined in {@code META-INF/batch-jobs/timer-scheduler-job1.xml} */ private static final String jobName = "timer-scheduler-job1"; /** * The full REST API URL, including scheme, hostname, port number, context path, servlet path for REST API. * For example, "http://localhost:8080/testApp/api" */ private static final String restUrl = BASE_URL + "scheduleTimer/api"; private static final String testNameKey = "testName"; private static final int initialDelayMinute = 1; private static final int intervalMinute = 1; private static final long sleepTimeMillis = initialDelayMinute * 60 * 1000 + 3000; private BatchClient batchClient = new BatchClient(restUrl); @Override protected BatchClient getBatchClient() { return batchClient; } /** * Tests single-action job scheudle specified with an initial delay. * This tests first cancels all job schedules to avoid left-over schedules. * * @throws Exception if errors occur */ @Test public void singleActionInitialDelay() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "singleActionInitialDelay"); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .initialDelay(initialDelayMinute) .build(); JobSchedule schedule = batchClient.schedule(scheduleConfig); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(schedule.getId()).getStatus()); System.out.printf("Scheduled job schedule: %s%n", schedule.getId()); Thread.sleep(sleepTimeMillis); schedule = batchClient.getJobSchedule(schedule.getId()); assertEquals(null, schedule); } /** * Tests repeatable job schedule specified with {@code javax.ejb.ScheduleExpression#second}. * This tests first cancels all job schedules to avoid left-over schedules. * * @throws Exception if errors occur */ @Test public void scheduleExpressionSecond() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "scheduleExpressionSecond"); final ScheduleExpression exp = new ScheduleExpression().hour("*").minute("*").second("0/20"); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .scheduleExpression(exp) .build(); JobSchedule schedule = batchClient.schedule(scheduleConfig); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(schedule.getId()).getStatus()); System.out.printf("Scheduled job schedule: %s%n", schedule.getId()); Thread.sleep(sleepTimeMillis); schedule = batchClient.getJobSchedule(schedule.getId()); assertEquals(JobSchedule.Status.SCHEDULED, schedule.getStatus()); System.out.printf("Job executions from above schedule: %s%n", schedule.getJobExecutionIds()); assertEquals(true, schedule.getJobExecutionIds().size() >= 2); assertEquals(true, cancelJobSchedule(schedule)); } /** * Tests repeatable job schedule specified with {@code javax.ejb.ScheduleExpression#second} * and {@code javax.ejb.ScheduleExpression#persistent}. * * This tests first cancels all job schedules to avoid left-over schedules. * @throws Exception if errors occur */ @Test public void scheduleExpressionPersistent() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "scheduleExpressionPersistent"); final ScheduleExpression exp = new ScheduleExpression().hour("*").minute("*").second("0/20"); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .scheduleExpression(exp) .persistent(true) .build(); JobSchedule schedule = batchClient.schedule(scheduleConfig); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(schedule.getId()).getStatus()); System.out.printf("Scheduled job schedule: %s%n", schedule.getId()); Thread.sleep(sleepTimeMillis); schedule = batchClient.getJobSchedule(schedule.getId()); assertEquals(JobSchedule.Status.SCHEDULED, schedule.getStatus()); System.out.printf("Job executions from above schedule: %s%n", schedule.getJobExecutionIds()); assertEquals(true, schedule.getJobExecutionIds().size() >= 2); assertEquals(true, cancelJobSchedule(schedule)); } /** * Tests repeatable job schedule specified with * {@code javax.ejb.ScheduleExpression#end} date. * * This tests first cancels all job schedules to avoid left-over schedules. * @throws Exception if errors occur */ @Test public void scheduleExpressionEnd() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "scheduleExpressionEnd"); final ScheduleExpression exp = new ScheduleExpression().hour("*").minute("*").second("0/20") .end(new Date(System.currentTimeMillis() + 60*1000)); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .scheduleExpression(exp) .build(); JobSchedule schedule = batchClient.schedule(scheduleConfig); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(schedule.getId()).getStatus()); System.out.printf("Scheduled job schedule: %s%n", schedule.getId()); //the job schedule should have ended due to the end attribute in ScheduleExpression Thread.sleep(sleepTimeMillis); schedule = batchClient.getJobSchedule(schedule.getId()); assertEquals(null, schedule); } /** * Tests repeatable job schedule specified with * {@code javax.ejb.ScheduleExpression#start} date. * * This tests first cancels all job schedules to avoid left-over schedules. * @throws Exception if errors occur */ @Test public void scheduleExpressionStart() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "scheduleExpressionStart"); final ScheduleExpression exp = new ScheduleExpression().hour("*").minute("*").second("0/1") .start(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1))); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .scheduleExpression(exp) .build(); JobSchedule schedule = batchClient.schedule(scheduleConfig); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(schedule.getId()).getStatus()); System.out.printf("Scheduled job schedule: %s%n", schedule.getId()); //the job schedule have not started due to the start attribute in ScheduleExpression Thread.sleep(sleepTimeMillis); schedule = batchClient.getJobSchedule(schedule.getId()); assertEquals(0, schedule.getJobExecutionIds().size()); assertEquals(true, cancelJobSchedule(schedule)); } /** * Tests repeatable job schedule specified with an initial delay and interval. * This tests first cancels all job schedules to avoid left-over schedules. * * @throws Exception if errors occur */ @Test public void scheduleInterval() throws Exception { cancelAllSchedules(); final Properties params = new Properties(); params.setProperty(testNameKey, "scheduleInterval"); final JobScheduleConfig scheduleConfig = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .initialDelay(initialDelayMinute) .interval(intervalMinute) .build(); final JobScheduleConfig scheduleConfig2 = JobScheduleConfigBuilder.newInstance() .jobName(jobName) .jobParameters(params) .initialDelay(initialDelayMinute * 10) .interval(intervalMinute) .build(); JobSchedule jobSchedule = batchClient.schedule(scheduleConfig); JobSchedule jobSchedule2 = batchClient.schedule(scheduleConfig2); System.out.printf("Scheduled job schedule: %s%n", jobSchedule.getId()); System.out.printf("Scheduled job schedule 2: %s%n", jobSchedule2.getId()); Thread.sleep(sleepTimeMillis * 2); try { jobSchedule = batchClient.getJobSchedule(jobSchedule.getId()); assertEquals(JobSchedule.Status.SCHEDULED, jobSchedule.getStatus()); assertEquals(JobSchedule.Status.SCHEDULED, batchClient.getJobSchedule(jobSchedule2.getId()).getStatus()); assertEquals(true, batchClient.getJobSchedules().length >= 2); assertEquals(2, jobSchedule.getJobExecutionIds().size()); assertEquals(BatchStatus.COMPLETED, batchClient.getJobExecution(jobSchedule.getJobExecutionIds().get(0)).getBatchStatus()); } finally { cancelJobSchedule(jobSchedule); cancelJobSchedule(jobSchedule2); } } /** * Cancels the job schedule, logs the cancellation status, and * returns the status (true or false). * * @param schedule the job schedule to cancel * @return true if cancelled successfully; false otherwise */ private boolean cancelJobSchedule(final JobSchedule schedule) { final String id = schedule.getId(); final boolean cancelled = batchClient.cancelJobSchedule(id); if (cancelled) { System.out.printf("Cancelled job schedule %s%n", id); } else { System.out.printf("Tried to cancel schedule %s, but failed.", id); } return cancelled; } /** * Retrieves all job schedules and cancel them one by one. */ private void cancelAllSchedules() { for (final JobSchedule e : batchClient.getJobSchedules()) { cancelJobSchedule(e); } } }