/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.launch;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.batch.api.AbstractBatchlet;
import javax.batch.api.Batchlet;
import javax.batch.operations.JobExecutionIsRunningException;
import javax.batch.operations.JobOperator;
import javax.batch.operations.JobRestartException;
import javax.batch.operations.JobStartException;
import javax.batch.operations.NoSuchJobException;
import javax.batch.operations.NoSuchJobExecutionException;
import javax.batch.operations.NoSuchJobInstanceException;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.DataSourceConfiguration;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.core.converter.JobParametersConverterSupport;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.SimpleJobExplorer;
import org.springframework.batch.core.jsr.AbstractJsrTestCase;
import org.springframework.batch.core.jsr.JsrJobParametersConverter;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.JobRepositorySupport;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class JsrJobOperatorTests extends AbstractJsrTestCase {
private JobOperator jsrJobOperator;
@Mock
private JobExplorer jobExplorer;
@Mock
private JobRepository jobRepository;
private JobParametersConverter parameterConverter;
private static final long TIMEOUT = 10000L;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
parameterConverter = new JobParametersConverterSupport();
jsrJobOperator = new JsrJobOperator(jobExplorer, jobRepository, parameterConverter, new ResourcelessTransactionManager());
}
@Test
public void testLoadingWithBatchRuntime() {
jsrJobOperator = BatchRuntime.getJobOperator();
assertNotNull(jsrJobOperator);
}
@Test
public void testNullsInConstructor() {
try {
new JsrJobOperator(null, new JobRepositorySupport(), parameterConverter, null);
fail("JobExplorer should be required");
} catch (IllegalArgumentException correct) {
}
try {
new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), null, parameterConverter, null);
fail("JobRepository should be required");
} catch (IllegalArgumentException correct) {
}
try {
new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), null, null);
fail("ParameterConverter should be required");
} catch (IllegalArgumentException correct) {
}
try {
new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), parameterConverter, null);
}
catch (IllegalArgumentException correct) {
}
new JsrJobOperator(new SimpleJobExplorer(null, null, null, null), new JobRepositorySupport(), parameterConverter, new ResourcelessTransactionManager());
}
@Test
public void testCustomBaseContextJsrCompliant() throws Exception {
System.setProperty("JSR-352-BASE-CONTEXT", "META-INF/alternativeJsrBaseContext.xml");
ReflectionTestUtils.setField(JsrJobOperator.BaseContextHolder.class, "instance", null);
JobOperator jobOperator = BatchRuntime.getJobOperator();
Object transactionManager = ReflectionTestUtils.getField(jobOperator, "transactionManager");
assertTrue(transactionManager instanceof ResourcelessTransactionManager);
long executionId = jobOperator.start("longRunningJob", null);
// Give the job a chance to get started
Thread.sleep(1000L);
jobOperator.stop(executionId);
// Give the job the chance to finish stopping
Thread.sleep(1000L);
assertEquals(BatchStatus.STOPPED, jobOperator.getJobExecution(executionId).getBatchStatus());
System.getProperties().remove("JSR-352-BASE-CONTEXT");
}
@Test
public void testCustomBaseContextCustomWired() throws Exception {
GenericApplicationContext context = new AnnotationConfigApplicationContext(BatchConfgiuration.class);
JobOperator jobOperator = (JobOperator) context.getBean("jobOperator");
assertEquals(context, ReflectionTestUtils.getField(jobOperator, "baseContext"));
long executionId = jobOperator.start("longRunningJob", null);
// Give the job a chance to get started
Thread.sleep(1000L);
jobOperator.stop(executionId);
// Give the job the chance to finish stopping
Thread.sleep(1000L);
assertEquals(BatchStatus.STOPPED, jobOperator.getJobExecution(executionId).getBatchStatus());
System.getProperties().remove("JSR-352-BASE-CONTEXT");
}
@Test
public void testDefaultTaskExecutor() throws Exception {
JsrJobOperator jsrJobOperatorImpl = (JsrJobOperator) jsrJobOperator;
jsrJobOperatorImpl.afterPropertiesSet();
assertNotNull(jsrJobOperatorImpl.getTaskExecutor());
assertTrue((jsrJobOperatorImpl.getTaskExecutor() instanceof AsyncTaskExecutor));
}
@Test
public void testCustomTaskExecutor() throws Exception {
JsrJobOperator jsrJobOperatorImpl = (JsrJobOperator) jsrJobOperator;
jsrJobOperatorImpl.setTaskExecutor(new SyncTaskExecutor());
jsrJobOperatorImpl.afterPropertiesSet();
assertNotNull(jsrJobOperatorImpl.getTaskExecutor());
assertTrue((jsrJobOperatorImpl.getTaskExecutor() instanceof SyncTaskExecutor));
}
@Test
public void testAbandonRoseyScenario() throws Exception {
JobExecution jobExecution = new JobExecution(5L);
jobExecution.setEndTime(new Date());
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
jsrJobOperator.abandon(5L);
ArgumentCaptor<JobExecution> executionCaptor = ArgumentCaptor.forClass(JobExecution.class);
verify(jobRepository).update(executionCaptor.capture());
assertEquals(org.springframework.batch.core.BatchStatus.ABANDONED, executionCaptor.getValue().getStatus());
}
@Test(expected=NoSuchJobExecutionException.class)
public void testAbandonNoSuchJob() throws Exception {
jsrJobOperator.abandon(5L);
}
@Test(expected=JobExecutionIsRunningException.class)
public void testAbandonJobRunning() throws Exception {
JobExecution jobExecution = new JobExecution(5L);
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
jsrJobOperator.abandon(5L);
}
@Test
public void testGetJobExecutionRoseyScenario() {
when(jobExplorer.getJobExecution(5L)).thenReturn(new JobExecution(5L));
assertEquals(5L, jsrJobOperator.getJobExecution(5L).getExecutionId());
}
@Test(expected=NoSuchJobExecutionException.class)
public void testGetJobExecutionNoExecutionFound() {
jsrJobOperator.getJobExecution(5L);
}
@Test
public void testGetJobExecutionsRoseyScenario() {
org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job");
List<JobExecution> executions = new ArrayList<JobExecution>();
executions.add(new JobExecution(2L));
when(jobExplorer.getJobExecutions(jobInstance)).thenReturn(executions);
List<javax.batch.runtime.JobExecution> jobExecutions = jsrJobOperator.getJobExecutions(jobInstance);
assertEquals(1, jobExecutions.size());
assertEquals(2L, executions.get(0).getId().longValue());
}
@Test(expected=NoSuchJobInstanceException.class)
public void testGetJobExecutionsNullJobInstance() {
jsrJobOperator.getJobExecutions(null);
}
@Test(expected=NoSuchJobInstanceException.class)
public void testGetJobExecutionsNullReturned() {
org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job");
jsrJobOperator.getJobExecutions(jobInstance);
}
@Test(expected=NoSuchJobInstanceException.class)
public void testGetJobExecutionsNoneReturned() {
org.springframework.batch.core.JobInstance jobInstance = new org.springframework.batch.core.JobInstance(5L, "my job");
List<JobExecution> executions = new ArrayList<JobExecution>();
when(jobExplorer.getJobExecutions(jobInstance)).thenReturn(executions);
jsrJobOperator.getJobExecutions(jobInstance);
}
@Test
public void testGetJobInstanceRoseyScenario() {
JobInstance instance = new JobInstance(1L, "my job");
JobExecution execution = new JobExecution(5L);
execution.setJobInstance(instance);
when(jobExplorer.getJobExecution(5L)).thenReturn(execution);
when(jobExplorer.getJobInstance(1L)).thenReturn(instance);
javax.batch.runtime.JobInstance jobInstance = jsrJobOperator.getJobInstance(5L);
assertEquals(1L, jobInstance.getInstanceId());
assertEquals("my job", jobInstance.getJobName());
}
@Test(expected=NoSuchJobExecutionException.class)
public void testGetJobInstanceNoExecution() {
JobInstance instance = new JobInstance(1L, "my job");
JobExecution execution = new JobExecution(5L);
execution.setJobInstance(instance);
jsrJobOperator.getJobInstance(5L);
}
@Test
public void testGetJobInstanceCount() throws Exception {
when(jobExplorer.getJobInstanceCount("myJob")).thenReturn(4);
assertEquals(4, jsrJobOperator.getJobInstanceCount("myJob"));
}
@Test(expected=NoSuchJobException.class)
public void testGetJobInstanceCountNoSuchJob() throws Exception {
when(jobExplorer.getJobInstanceCount("myJob")).thenThrow(new org.springframework.batch.core.launch.NoSuchJobException("expected"));
jsrJobOperator.getJobInstanceCount("myJob");
}
@Test(expected=NoSuchJobException.class)
public void testGetJobInstanceCountZeroInstancesReturned() throws Exception {
when(jobExplorer.getJobInstanceCount("myJob")).thenReturn(0);
jsrJobOperator.getJobInstanceCount("myJob");
}
@Test
public void testGetJobInstancesRoseyScenario() {
List<JobInstance> instances = new ArrayList<JobInstance>();
instances.add(new JobInstance(1L, "myJob"));
instances.add(new JobInstance(2L, "myJob"));
instances.add(new JobInstance(3L, "myJob"));
when(jobExplorer.getJobInstances("myJob", 0, 3)).thenReturn(instances);
List<javax.batch.runtime.JobInstance> jobInstances = jsrJobOperator.getJobInstances("myJob", 0, 3);
assertEquals(3, jobInstances.size());
assertEquals(1L, jobInstances.get(0).getInstanceId());
assertEquals(2L, jobInstances.get(1).getInstanceId());
assertEquals(3L, jobInstances.get(2).getInstanceId());
}
@Test(expected=NoSuchJobException.class)
public void testGetJobInstancesNullInstancesReturned() {
jsrJobOperator.getJobInstances("myJob", 0, 3);
}
@Test(expected=NoSuchJobException.class)
public void testGetJobInstancesZeroInstancesReturned() {
List<JobInstance> instances = new ArrayList<JobInstance>();
when(jobExplorer.getJobInstances("myJob", 0, 3)).thenReturn(instances);
jsrJobOperator.getJobInstances("myJob", 0, 3);
}
@Test
public void testGetJobNames() {
List<String> jobNames = new ArrayList<String>();
jobNames.add("job1");
jobNames.add("job2");
when(jobExplorer.getJobNames()).thenReturn(jobNames);
Set<String> result = jsrJobOperator.getJobNames();
assertEquals(2, result.size());
assertTrue(result.contains("job1"));
assertTrue(result.contains("job2"));
}
@Test
public void testGetParametersRoseyScenario() {
JobExecution jobExecution = new JobExecution(5L, new JobParametersBuilder().addString("key1", "value1").addLong(JsrJobParametersConverter.JOB_RUN_ID, 5L).toJobParameters());
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
Properties params = jsrJobOperator.getParameters(5L);
assertEquals("value1", params.get("key1"));
assertNull(params.get(JsrJobParametersConverter.JOB_RUN_ID));
}
@Test(expected=NoSuchJobExecutionException.class)
public void testGetParametersNoExecution() {
jsrJobOperator.getParameters(5L);
}
@Test(expected=NoSuchJobException.class)
public void testGetNoRunningExecutions() {
Set<JobExecution> executions = new HashSet<JobExecution>();
when(jobExplorer.findRunningJobExecutions("myJob")).thenReturn(executions);
jsrJobOperator.getRunningExecutions("myJob");
}
@Test
public void testGetRunningExecutions() {
Set<JobExecution> executions = new HashSet<JobExecution>();
executions.add(new JobExecution(5L));
when(jobExplorer.findRunningJobExecutions("myJob")).thenReturn(executions);
assertEquals(5L, jsrJobOperator.getRunningExecutions("myJob").get(0).longValue());
}
@Test
public void testGetStepExecutionsRoseyScenario() {
JobExecution jobExecution = new JobExecution(5L);
List<StepExecution> stepExecutions = new ArrayList<StepExecution>();
stepExecutions.add(new StepExecution("step1", jobExecution, 1L));
stepExecutions.add(new StepExecution("step2", jobExecution, 2L));
jobExecution.addStepExecutions(stepExecutions);
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
when(jobExplorer.getStepExecution(5L, 1L)).thenReturn(new StepExecution("step1", jobExecution, 1L));
when(jobExplorer.getStepExecution(5L, 2L)).thenReturn(new StepExecution("step2", jobExecution, 2L));
List<javax.batch.runtime.StepExecution> results = jsrJobOperator.getStepExecutions(5L);
assertEquals("step1", results.get(0).getStepName());
assertEquals("step2", results.get(1).getStepName());
}
@Test(expected=NoSuchJobException.class)
public void testGetStepExecutionsNoExecutionReturned() {
jsrJobOperator.getStepExecutions(5L);
}
@Test
public void testGetStepExecutionsPartitionedStepScenario() {
JobExecution jobExecution = new JobExecution(5L);
List<StepExecution> stepExecutions = new ArrayList<StepExecution>();
stepExecutions.add(new StepExecution("step1", jobExecution, 1L));
stepExecutions.add(new StepExecution("step2", jobExecution, 2L));
stepExecutions.add(new StepExecution("step2:partition0", jobExecution, 2L));
stepExecutions.add(new StepExecution("step2:partition1", jobExecution, 2L));
stepExecutions.add(new StepExecution("step2:partition2", jobExecution, 2L));
jobExecution.addStepExecutions(stepExecutions);
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
when(jobExplorer.getStepExecution(5L, 1L)).thenReturn(new StepExecution("step1", jobExecution, 1L));
when(jobExplorer.getStepExecution(5L, 2L)).thenReturn(new StepExecution("step2", jobExecution, 2L));
List<javax.batch.runtime.StepExecution> results = jsrJobOperator.getStepExecutions(5L);
assertEquals("step1", results.get(0).getStepName());
assertEquals("step2", results.get(1).getStepName());
}
@Test
public void testGetStepExecutionsNoStepExecutions() {
JobExecution jobExecution = new JobExecution(5L);
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
List<javax.batch.runtime.StepExecution> results = jsrJobOperator.getStepExecutions(5L);
assertEquals(0, results.size());
}
@Test
public void testStartRoseyScenario() throws Exception {
javax.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT);
assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus());
}
@Test
public void testStartMultipleTimesSameParameters() throws Exception {
jsrJobOperator = BatchRuntime.getJobOperator();
int jobInstanceCountBefore = 0;
try {
jobInstanceCountBefore = jsrJobOperator.getJobInstanceCount("myJob3");
} catch (NoSuchJobException ignore) {
}
javax.batch.runtime.JobExecution execution1 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT);
javax.batch.runtime.JobExecution execution2 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT);
javax.batch.runtime.JobExecution execution3 = runJob("jsrJobOperatorTestJob", new Properties(), TIMEOUT);
assertEquals(BatchStatus.COMPLETED, execution1.getBatchStatus());
assertEquals(BatchStatus.COMPLETED, execution2.getBatchStatus());
assertEquals(BatchStatus.COMPLETED, execution3.getBatchStatus());
int jobInstanceCountAfter = jsrJobOperator.getJobInstanceCount("myJob3");
assertTrue((jobInstanceCountAfter - jobInstanceCountBefore) == 3);
}
@Test
public void testRestartRoseyScenario() throws Exception {
javax.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestRestartJob", new Properties(), TIMEOUT);
assertEquals(BatchStatus.FAILED, execution.getBatchStatus());
execution = restartJob(execution.getExecutionId(), null, TIMEOUT);
assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus());
}
@Test(expected = JobRestartException.class)
public void testNonRestartableJob() throws Exception {
javax.batch.runtime.JobExecution jobExecutionStart = runJob("jsrJobOperatorTestNonRestartableJob", new Properties(), TIMEOUT);
assertEquals(BatchStatus.FAILED, jobExecutionStart.getBatchStatus());
restartJob(jobExecutionStart.getExecutionId(), null, TIMEOUT);
}
@Test(expected = JobRestartException.class)
public void testRestartAbandoned() throws Exception {
jsrJobOperator = BatchRuntime.getJobOperator();
javax.batch.runtime.JobExecution execution = runJob("jsrJobOperatorTestRestartAbandonJob", null, TIMEOUT);
assertEquals(BatchStatus.FAILED, execution.getBatchStatus());
jsrJobOperator.abandon(execution.getExecutionId());
jsrJobOperator.restart(execution.getExecutionId(), null);
}
@Test
public void testGetNoRestartJobParameters() {
JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator;
Properties properties = jobOperator.getJobRestartProperties(null, null);
assertTrue(properties.isEmpty());
}
@Test
public void testGetRestartJobParameters() {
JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator;
JobExecution jobExecution = new JobExecution(1L,
new JobParametersBuilder().addString("prevKey1", "prevVal1").toJobParameters());
Properties userProperties = new Properties();
userProperties.put("userKey1", "userVal1");
Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution);
assertTrue(properties.size() == 2);
assertTrue(properties.getProperty("prevKey1").equals("prevVal1"));
assertTrue(properties.getProperty("userKey1").equals("userVal1"));
}
@Test
public void testGetRestartJobParametersWithDefaults() {
JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator;
JobExecution jobExecution = new JobExecution(1L,
new JobParametersBuilder().addString("prevKey1", "prevVal1").addString("prevKey2", "prevVal2").toJobParameters());
Properties defaultProperties = new Properties();
defaultProperties.setProperty("prevKey2", "not value 2");
Properties userProperties = new Properties(defaultProperties);
Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution);
assertTrue(properties.size() == 2);
assertTrue(properties.getProperty("prevKey1").equals("prevVal1"));
assertTrue("prevKey2 = " + properties.getProperty("prevKey2"), properties.getProperty("prevKey2").equals("not value 2"));
}
@Test
public void testNewJobParametersOverridePreviousRestartParameters() {
JsrJobOperator jobOperator = (JsrJobOperator) jsrJobOperator;
JobExecution jobExecution = new JobExecution(1L,
new JobParametersBuilder()
.addString("prevKey1", "prevVal1")
.addString("overrideTest", "jobExecution")
.toJobParameters());
Properties userProperties = new Properties();
userProperties.put("userKey1", "userVal1");
userProperties.put("overrideTest", "userProperties");
Properties properties = jobOperator.getJobRestartProperties(userProperties, jobExecution);
assertTrue(properties.size() == 3);
assertTrue(properties.getProperty("prevKey1").equals("prevVal1"));
assertTrue(properties.getProperty("userKey1").equals("userVal1"));
assertTrue(properties.getProperty("overrideTest").equals("userProperties"));
}
@Test(expected = JobStartException.class)
public void testBeanCreationExceptionOnStart() throws Exception {
jsrJobOperator = BatchRuntime.getJobOperator();
try {
jsrJobOperator.start("jsrJobOperatorTestBeanCreationException", null);
} catch (JobStartException e) {
assertTrue(e.getCause() instanceof BeanCreationException);
throw e;
}
fail("Should have failed");
}
@SuppressWarnings("unchecked")
@Test(expected=JobStartException.class)
public void testStartUnableToCreateJobExecution() throws Exception {
when(jobRepository.createJobExecution("myJob", null)).thenThrow(RuntimeException.class);
jsrJobOperator.start("myJob", null);
}
@Test
public void testJobStopRoseyScenario() throws Exception {
jsrJobOperator = BatchRuntime.getJobOperator();
long executionId = jsrJobOperator.start("longRunningJob", null);
// Give the job a chance to get started
Thread.sleep(1000L);
jsrJobOperator.stop(executionId);
// Give the job the chance to finish stopping
Thread.sleep(1000L);
assertEquals(BatchStatus.STOPPED, jsrJobOperator.getJobExecution(executionId).getBatchStatus());
}
@Test
public void testApplicationContextClosingAfterJobSuccessful() throws Exception {
for(int i = 0; i < 3; i++) {
javax.batch.runtime.JobExecution execution = runJob("contextClosingTests", new Properties(), TIMEOUT);
assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus());
// Added to allow time for the context to finish closing before running the job again
Thread.sleep(1000l);
}
}
public static class LongRunningBatchlet implements Batchlet {
private boolean stopped = false;
@Override
public String process() throws Exception {
while(!stopped) {
Thread.sleep(250);
}
return null;
}
@Override
public void stop() throws Exception {
stopped = true;
}
}
public static class FailingBatchlet extends AbstractBatchlet {
@Override
public String process() throws Exception {
throw new RuntimeException("blah");
}
}
public static class MustBeClosedBatchlet extends AbstractBatchlet {
public static boolean closed = true;
public MustBeClosedBatchlet() {
if(!closed) {
throw new RuntimeException("Batchlet wasn't closed last time");
}
}
public void close() {
closed = true;
}
@Override
public String process() throws Exception {
closed = false;
return null;
}
}
@Configuration
@Import(DataSourceConfiguration.class)
@EnableBatchProcessing
public static class BatchConfgiuration {
@Bean
public JsrJobOperator jobOperator(JobExplorer jobExplorer, JobRepository jobrepository, DataSource dataSource,
PlatformTransactionManager transactionManager) throws Exception{
JsrJobParametersConverter jobParametersConverter = new JsrJobParametersConverter(dataSource);
jobParametersConverter.afterPropertiesSet();
return new JsrJobOperator(jobExplorer, jobrepository, jobParametersConverter, transactionManager);
}
}
}