[BATCH-429] Moved all code out of execution
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public abstract class AbstractExceptionTests extends TestCase {
|
||||
|
||||
public void testExceptionString() throws Exception {
|
||||
Exception exception = getException("foo");
|
||||
assertEquals("foo", exception.getMessage());
|
||||
}
|
||||
|
||||
public void testExceptionStringThrowable() throws Exception {
|
||||
Exception exception = getException("foo", new IllegalStateException());
|
||||
assertEquals("foo", exception.getMessage().substring(0, 3));
|
||||
}
|
||||
|
||||
public abstract Exception getException(String msg) throws Exception;
|
||||
|
||||
public abstract Exception getException(String msg, Throwable t) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.configuration;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.repository.DuplicateJobException;
|
||||
import org.springframework.batch.core.repository.NoSuchJobException;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobRegistryBeanPostProcessorTests extends TestCase {
|
||||
|
||||
private JobRegistryBeanPostProcessor processor = new JobRegistryBeanPostProcessor();
|
||||
|
||||
public void testInitialization() throws Exception {
|
||||
try {
|
||||
processor.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
assertTrue(e.getMessage().indexOf("JobConfigurationRegistry") >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBeforeInitialization() throws Exception {
|
||||
// should be a no-op
|
||||
assertEquals("foo", processor.postProcessAfterInitialization("foo",
|
||||
"bar"));
|
||||
}
|
||||
|
||||
public void testAfterInitializationWithWrongType() throws Exception {
|
||||
// should be a no-op
|
||||
assertEquals("foo", processor.postProcessAfterInitialization("foo",
|
||||
"bar"));
|
||||
}
|
||||
|
||||
public void testAfterInitializationWithCorrectType() throws Exception {
|
||||
MapJobRegistry registry = new MapJobRegistry();
|
||||
processor.setJobRegistry(registry);
|
||||
JobSupport configuration = new JobSupport();
|
||||
configuration.setBeanName("foo");
|
||||
assertEquals(configuration, processor.postProcessAfterInitialization(
|
||||
configuration, "bar"));
|
||||
assertEquals(configuration, registry.getJob("foo"));
|
||||
}
|
||||
|
||||
public void testAfterInitializationWithDuplicate() throws Exception {
|
||||
MapJobRegistry registry = new MapJobRegistry();
|
||||
processor.setJobRegistry(registry);
|
||||
JobSupport configuration = new JobSupport();
|
||||
configuration.setBeanName("foo");
|
||||
processor.postProcessAfterInitialization(configuration, "bar");
|
||||
try {
|
||||
processor.postProcessAfterInitialization(configuration, "spam");
|
||||
fail("Expected FatalBeanException");
|
||||
} catch (FatalBeanException e) {
|
||||
// Expected
|
||||
assertTrue(e.getCause() instanceof DuplicateJobException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testUnregisterOnDestroy() throws Exception {
|
||||
MapJobRegistry registry = new MapJobRegistry();
|
||||
processor.setJobRegistry(registry);
|
||||
JobSupport configuration = new JobSupport();
|
||||
configuration.setBeanName("foo");
|
||||
assertEquals(configuration, processor.postProcessAfterInitialization(
|
||||
configuration, "bar"));
|
||||
processor.destroy();
|
||||
try {
|
||||
assertEquals(null, registry.getJob("foo"));
|
||||
fail("Expected NoSuchJobConfigurationException");
|
||||
} catch (NoSuchJobException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testExecutionWithApplicationContext() throws Exception {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"test-context.xml", getClass());
|
||||
MapJobRegistry registry = (MapJobRegistry) context
|
||||
.getBean("registry");
|
||||
Collection configurations = registry.getJobNames();
|
||||
// System.err.println(configurations);
|
||||
String[] names = context.getBeanNamesForType(JobSupport.class);
|
||||
int count = names.length;
|
||||
// Each concrete bean of type JobConfiguration is registered...
|
||||
assertEquals(count, configurations.size());
|
||||
// N.B. there is a failure / wonky mode where a parent bean is given an
|
||||
// explicit name or beanName (using property setter): in this case then
|
||||
// child beans will have the same name and will be re-registered (and
|
||||
// override, if the registry supports that).
|
||||
assertNotNull(registry.getJob("test-job"));
|
||||
assertEquals(context.getBean("test-job-with-name"), registry
|
||||
.getJob("foo"));
|
||||
assertEquals(context.getBean("test-job-with-bean-name"), registry
|
||||
.getJob("bar"));
|
||||
assertEquals(context.getBean("test-job-with-parent-and-name"), registry
|
||||
.getJob("spam"));
|
||||
assertEquals(context.getBean("test-job-with-parent-and-bean-name"),
|
||||
registry.getJob("bucket"));
|
||||
assertEquals(context.getBean("test-job-with-concrete-parent"), registry
|
||||
.getJob("maps"));
|
||||
assertEquals(context.getBean("test-job-with-concrete-parent-and-name"),
|
||||
registry.getJob("oof"));
|
||||
assertEquals(context
|
||||
.getBean("test-job-with-concrete-parent-and-bean-name"),
|
||||
registry.getJob("rab"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.configuration;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.configuration.JobFactory;
|
||||
import org.springframework.batch.core.repository.DuplicateJobException;
|
||||
import org.springframework.batch.core.repository.NoSuchJobException;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class MapJobRegistryTests extends TestCase {
|
||||
|
||||
private MapJobRegistry registry = new MapJobRegistry();
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.configuration.MapJobRegistry#unregister(String)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testUnregister() throws Exception {
|
||||
registry.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
assertNotNull(registry.getJob("foo"));
|
||||
registry.unregister("foo");
|
||||
try {
|
||||
assertNull(registry.getJob("foo"));
|
||||
fail("Expected NoSuchJobConfigurationException");
|
||||
}
|
||||
catch (NoSuchJobException e) {
|
||||
// expected
|
||||
assertTrue(e.getMessage().indexOf("foo")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.configuration.MapJobRegistry#getJob(java.lang.String)}.
|
||||
*/
|
||||
public void testReplaceDuplicateConfiguration() throws Exception {
|
||||
registry.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
try {
|
||||
registry.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
fail("Expected DuplicateJobConfigurationException");
|
||||
} catch (DuplicateJobException e) {
|
||||
// unexpected: even if the job is different we want a DuplicateJobException
|
||||
assertTrue(e.getMessage().indexOf("foo")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.configuration.MapJobRegistry#getJob(java.lang.String)}.
|
||||
*/
|
||||
public void testRealDuplicateConfiguration() throws Exception {
|
||||
JobFactory jobFactory = new ReferenceJobFactory(new JobSupport("foo"));
|
||||
registry.register(jobFactory);
|
||||
try {
|
||||
registry.register(jobFactory);
|
||||
fail("Unexpected DuplicateJobConfigurationException");
|
||||
} catch (DuplicateJobException e) {
|
||||
// expected
|
||||
assertTrue(e.getMessage().indexOf("foo")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.configuration.MapJobRegistry#getJobNames()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetJobConfigurations() throws Exception {
|
||||
JobFactory jobFactory = new ReferenceJobFactory(new JobSupport("foo"));
|
||||
registry.register(jobFactory);
|
||||
registry.register(new ReferenceJobFactory(new JobSupport("bar")));
|
||||
Collection configurations = registry.getJobNames();
|
||||
assertEquals(2, configurations.size());
|
||||
assertTrue(configurations.contains(jobFactory.getJobName()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.job;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class AbstractJobTests extends TestCase {
|
||||
|
||||
JobSupport job = new JobSupport("job");
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#JobConfiguration()}.
|
||||
*/
|
||||
public void testJobConfiguration() {
|
||||
job = new JobSupport();
|
||||
assertNull(job.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
*/
|
||||
public void testSetBeanName() {
|
||||
job.setBeanName("foo");
|
||||
assertEquals("job", job.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
*/
|
||||
public void testSetBeanNameWithNullName() {
|
||||
job = new JobSupport(null);
|
||||
assertEquals(null, job.getName());
|
||||
job.setBeanName("foo");
|
||||
assertEquals("foo", job.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#setStepNames(java.util.List)}.
|
||||
*/
|
||||
public void testSetSteps() {
|
||||
job.setSteps(Collections.singletonList(new StepSupport("step")));
|
||||
assertEquals(1, job.getSteps().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#addStepName(org.springframework.batch.core.configuration.StepConfiguration)}.
|
||||
*/
|
||||
public void testAddStep() {
|
||||
job.addStep(new StepSupport("step"));
|
||||
assertEquals(1, job.getSteps().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#setStartLimit(int)}.
|
||||
*/
|
||||
public void testSetStartLimit() {
|
||||
assertEquals(Integer.MAX_VALUE, job.getStartLimit());
|
||||
job.setStartLimit(10);
|
||||
assertEquals(10, job.getStartLimit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.job.AbstractJob#setRestartable(boolean)}.
|
||||
*/
|
||||
public void testSetRestartable() {
|
||||
assertFalse(job.isRestartable());
|
||||
job.setRestartable(true);
|
||||
assertTrue(job.isRestartable());
|
||||
}
|
||||
|
||||
public void testToString() throws Exception {
|
||||
String value = job.toString();
|
||||
assertTrue("Should contain name: "+value, value.indexOf("name=")>=0);
|
||||
}
|
||||
|
||||
public void testRunNotSupported() throws Exception {
|
||||
try {
|
||||
job.execute(null);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// expected
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain JobSupport: "+message, message.contains("JobSupport"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Batch domain object representing a job. Job is an explicit abstraction
|
||||
* representing the configuration of a job specified by a developer. It should
|
||||
* be noted that restart policy is applied to the job as a whole and not to a
|
||||
* step.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class JobSupport implements BeanNameAware, Job {
|
||||
|
||||
private List steps = new ArrayList();
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean restartable = false;
|
||||
|
||||
private int startLimit = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public JobSupport() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor to immediately add name (which is mandatory but
|
||||
* not final).
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public JobSupport(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name property if it is not already set. Because of the order of
|
||||
* the callbacks in a Spring container the name property will be set first
|
||||
* if it is present. Care is needed with bean definition inheritance - if a
|
||||
* parent bean has a name, then its children need an explicit name as well,
|
||||
* otherwise they will not be unique.
|
||||
*
|
||||
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setBeanName(String name) {
|
||||
if (this.name == null) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name property. Always overrides the default value if this object
|
||||
* is a Spring bean.
|
||||
*
|
||||
* @see #setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.IJob#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.IJob#getSteps()
|
||||
*/
|
||||
public List getSteps() {
|
||||
return steps;
|
||||
}
|
||||
|
||||
public void setSteps(List steps) {
|
||||
this.steps.clear();
|
||||
this.steps.addAll(steps);
|
||||
}
|
||||
|
||||
public void addStep(Step step) {
|
||||
this.steps.add(step);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.IJob#getStartLimit()
|
||||
*/
|
||||
public int getStartLimit() {
|
||||
return startLimit;
|
||||
}
|
||||
|
||||
public void setStartLimit(int startLimit) {
|
||||
this.startLimit = startLimit;
|
||||
}
|
||||
|
||||
public void setRestartable(boolean restartable) {
|
||||
this.restartable = restartable;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.IJob#isRestartable()
|
||||
*/
|
||||
public boolean isRestartable() {
|
||||
return restartable;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.Job#run(org.springframework.batch.core.domain.JobExecution)
|
||||
*/
|
||||
public void execute(JobExecution execution) throws UnexpectedJobExecutionException {
|
||||
throw new UnsupportedOperationException("JobSupport does not provide an implementation of run(). Use a smarter subclass.");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ClassUtils.getShortName(getClass()) + ": [name=" + name + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.listener.JobListenerSupport;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.JobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.JobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.StepExecutionDao;
|
||||
import org.springframework.batch.execution.step.AbstractStep;
|
||||
import org.springframework.batch.execution.step.support.NeverSkipItemSkipPolicy;
|
||||
import org.springframework.batch.item.AbstractItemReader;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.exception.ExceptionHandler;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
/**
|
||||
* Tests for DefaultJobLifecycle. MapJobDao and MapStepExecutionDao are used instead of a mock repository to test that
|
||||
* status is being stored correctly.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*/
|
||||
public class SimpleJobTests extends TestCase {
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private JobInstanceDao jobInstanceDao;
|
||||
|
||||
private JobExecutionDao jobExecutionDao;
|
||||
|
||||
private StepExecutionDao stepExecutionDao;
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private JobExecution jobExecution;
|
||||
|
||||
private StepExecution stepExecution1;
|
||||
|
||||
private StepExecution stepExecution2;
|
||||
|
||||
private StubStep stepConfiguration1;
|
||||
|
||||
private StubStep stepConfiguration2;
|
||||
|
||||
private JobParameters jobParameters = new JobParameters();
|
||||
|
||||
private SimpleJob job;
|
||||
|
||||
private Step step1;
|
||||
|
||||
private Step step2;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MapJobInstanceDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
jobInstanceDao = new MapJobInstanceDao();
|
||||
jobExecutionDao = new MapJobExecutionDao();
|
||||
stepExecutionDao = new MapStepExecutionDao();
|
||||
jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao);
|
||||
job = new SimpleJob();
|
||||
job.setJobRepository(jobRepository);
|
||||
|
||||
stepConfiguration1 = new StubStep("TestStep1");
|
||||
stepConfiguration1.setCallback(new Runnable() {
|
||||
public void run() {
|
||||
list.add("default");
|
||||
}
|
||||
});
|
||||
stepConfiguration2 = new StubStep("TestStep2");
|
||||
stepConfiguration2.setCallback(new Runnable() {
|
||||
public void run() {
|
||||
list.add("default");
|
||||
}
|
||||
});
|
||||
stepConfiguration1.setJobRepository(jobRepository);
|
||||
stepConfiguration2.setJobRepository(jobRepository);
|
||||
|
||||
List stepConfigurations = new ArrayList();
|
||||
stepConfigurations.add(stepConfiguration1);
|
||||
stepConfigurations.add(stepConfiguration2);
|
||||
job.setName("testJob");
|
||||
job.setSteps(stepConfigurations);
|
||||
|
||||
jobExecution = jobRepository.createJobExecution(job, jobParameters);
|
||||
jobInstance = jobExecution.getJobInstance();
|
||||
|
||||
List steps = jobInstance.getJob().getSteps();
|
||||
step1 = (Step) steps.get(0);
|
||||
step2 = (Step) steps.get(1);
|
||||
stepExecution1 = new StepExecution(step1, jobExecution, null);
|
||||
stepExecution2 = new StepExecution(step2, jobExecution, null);
|
||||
|
||||
}
|
||||
|
||||
// Test to ensure the exit status returned by the last step is returned
|
||||
public void testExitStatusReturned() throws JobExecutionException {
|
||||
|
||||
final ExitStatus customStatus = new ExitStatus(true, "test");
|
||||
|
||||
Step testStep = new Step() {
|
||||
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException {
|
||||
stepExecution.setExitStatus(customStatus);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
public int getStartLimit() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean isAllowStartIfComplete() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
List steps = new ArrayList();
|
||||
steps.add(testStep);
|
||||
job.setSteps(steps);
|
||||
job.execute(jobExecution);
|
||||
assertEquals(customStatus, jobExecution.getExitStatus());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testRunNormally() throws Exception {
|
||||
stepConfiguration1.setStartLimit(5);
|
||||
stepConfiguration2.setStartLimit(5);
|
||||
job.execute(jobExecution);
|
||||
assertEquals(2, list.size());
|
||||
checkRepository(BatchStatus.COMPLETED);
|
||||
assertNotNull(jobExecution.getEndTime());
|
||||
assertNotNull(jobExecution.getStartTime());
|
||||
}
|
||||
|
||||
public void testRunNormallyWithListener() throws Exception {
|
||||
job.setJobListeners(new JobListenerSupport[] { new JobListenerSupport() {
|
||||
public void beforeJob(JobExecution jobExecution) {
|
||||
list.add("before");
|
||||
}
|
||||
|
||||
public void afterJob(JobExecution jobExecution) {
|
||||
list.add("after");
|
||||
}
|
||||
} });
|
||||
job.execute(jobExecution);
|
||||
assertEquals(4, list.size());
|
||||
}
|
||||
|
||||
public void testRunWithSimpleStepExecutor() throws Exception {
|
||||
|
||||
job.setJobRepository(jobRepository);
|
||||
// do not set StepExecutorFactory...
|
||||
stepConfiguration1.setStartLimit(5);
|
||||
stepConfiguration1.setItemReader(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
list.add("1");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
stepConfiguration2.setStartLimit(5);
|
||||
stepConfiguration2.setItemReader(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
list.add("2");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
job.execute(jobExecution);
|
||||
assertEquals(2, list.size());
|
||||
checkRepository(BatchStatus.COMPLETED, ExitStatus.FINISHED);
|
||||
|
||||
}
|
||||
|
||||
public void testExecutionContextIsSet() throws Exception {
|
||||
testRunNormally();
|
||||
assertEquals(jobInstance, jobExecution.getJobInstance());
|
||||
assertEquals(2, jobExecution.getStepExecutions().size());
|
||||
assertEquals(step1.getName(), stepExecution1.getStepName());
|
||||
assertEquals(step2.getName(), stepExecution2.getStepName());
|
||||
}
|
||||
|
||||
public void testInterrupted() throws Exception {
|
||||
stepConfiguration1.setStartLimit(5);
|
||||
stepConfiguration2.setStartLimit(5);
|
||||
final JobInterruptedException exception = new JobInterruptedException("Interrupt!");
|
||||
stepConfiguration1.setProcessException(exception);
|
||||
try {
|
||||
job.execute(jobExecution);
|
||||
} catch (UnexpectedJobExecutionException e) {
|
||||
assertEquals(exception, e.getCause());
|
||||
}
|
||||
assertEquals(0, list.size());
|
||||
checkRepository(BatchStatus.STOPPED, ExitStatus.INTERRUPTED);
|
||||
}
|
||||
|
||||
public void testFailed() throws Exception {
|
||||
stepConfiguration1.setStartLimit(5);
|
||||
stepConfiguration2.setStartLimit(5);
|
||||
final RuntimeException exception = new RuntimeException("Foo!");
|
||||
stepConfiguration1.setProcessException(exception);
|
||||
try {
|
||||
job.execute(jobExecution);
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals(exception, e);
|
||||
}
|
||||
assertEquals(0, list.size());
|
||||
checkRepository(BatchStatus.FAILED, ExitStatus.FAILED);
|
||||
}
|
||||
|
||||
public void testStepShouldNotStart() throws Exception {
|
||||
// Start policy will return false, keeping the step from being started.
|
||||
stepConfiguration1.setStartLimit(0);
|
||||
|
||||
try {
|
||||
job.execute(jobExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
// expected
|
||||
assertTrue("Wrong message in exception: " + ex.getMessage(), ex.getMessage()
|
||||
.indexOf("start limit exceeded") >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testNoSteps() throws Exception {
|
||||
job.setSteps(new ArrayList());
|
||||
|
||||
job.execute(jobExecution);
|
||||
ExitStatus exitStatus = jobExecution.getExitStatus();
|
||||
assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().indexOf(
|
||||
"No steps configured") >= 0);
|
||||
}
|
||||
|
||||
// public void testNoStepsExecuted() throws Exception {
|
||||
// StepExecution completedExecution = new StepExecution("completedExecution", jobExecution);
|
||||
// completedExecution.setStatus(BatchStatus.COMPLETED);
|
||||
//
|
||||
// job.execute(jobExecution);
|
||||
// ExitStatus exitStatus = jobExecution.getExitStatus();
|
||||
// assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode());
|
||||
// assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().contains(
|
||||
// "steps already completed"));
|
||||
// }
|
||||
|
||||
public void testNotExecutedIfAlreadyStopped() throws Exception {
|
||||
jobExecution.stop();
|
||||
try {
|
||||
job.execute(jobExecution);
|
||||
} catch (UnexpectedJobExecutionException e) {
|
||||
assertTrue(e.getCause() instanceof JobInterruptedException);
|
||||
}
|
||||
assertEquals(0, list.size());
|
||||
checkRepository(BatchStatus.STOPPED, ExitStatus.NOOP);
|
||||
ExitStatus exitStatus = jobExecution.getExitStatus();
|
||||
assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode());
|
||||
}
|
||||
|
||||
/*
|
||||
* Check JobRepository to ensure status is being saved.
|
||||
*/
|
||||
private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
|
||||
assertEquals(jobInstance, jobInstanceDao.getJobInstance(jobInstance.getJob(), jobParameters));
|
||||
// because map dao stores in memory, it can be checked directly
|
||||
JobExecution jobExecution = (JobExecution) jobExecutionDao.findJobExecutions(jobInstance).get(0);
|
||||
assertEquals(jobInstance.getId(), jobExecution.getJobId());
|
||||
assertEquals(status, jobExecution.getStatus());
|
||||
if (exitStatus != null) {
|
||||
assertEquals(jobExecution.getExitStatus().getExitCode(), exitStatus.getExitCode());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRepository(BatchStatus status) {
|
||||
checkRepository(status, null);
|
||||
}
|
||||
|
||||
private class StubStep extends AbstractStep {
|
||||
|
||||
private Runnable runnable;
|
||||
private Exception exception;
|
||||
protected ExceptionHandler exceptionHandler;
|
||||
protected RetryPolicy retryPolicy;
|
||||
protected JobRepository jobRepository;
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
protected ItemReader itemReader;
|
||||
protected ItemWriter itemWriter;
|
||||
protected ItemSkipPolicy itemSkipPolicy = new NeverSkipItemSkipPolicy();
|
||||
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public StubStep(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param exception
|
||||
*/
|
||||
public void setProcessException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param runnable
|
||||
*/
|
||||
public void setCallback(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException {
|
||||
if (exception instanceof RuntimeException) {
|
||||
stepExecution.setExitStatus(ExitStatus.FAILED);
|
||||
throw (RuntimeException) exception;
|
||||
}
|
||||
if (exception instanceof JobInterruptedException) {
|
||||
stepExecution.setExitStatus(ExitStatus.INTERRUPTED);
|
||||
throw (JobInterruptedException) exception;
|
||||
}
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
stepExecution.setExitStatus(ExitStatus.FINISHED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name property. Always overrides the default value if this object is a Spring bean.
|
||||
*
|
||||
* @see #setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link RetryPolicy}.
|
||||
*
|
||||
* @param retryPolicy the {@link RetryPolicy} to set
|
||||
*/
|
||||
public void setRetryPolicy(RetryPolicy retryPolicy) {
|
||||
this.retryPolicy = retryPolicy;
|
||||
}
|
||||
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for {@link JobRepository}.
|
||||
*
|
||||
* @param jobRepository is a mandatory dependence (no default).
|
||||
*/
|
||||
public void setJobRepository(JobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link PlatformTransactionManager}.
|
||||
*
|
||||
* @param transactionManager the transaction manager to set
|
||||
*/
|
||||
public void setTransactionManager(PlatformTransactionManager transactionManager) {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemReader the itemReader to set
|
||||
*/
|
||||
public void setItemReader(ItemReader itemReader) {
|
||||
this.itemReader = itemReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemWriter the itemWriter to set
|
||||
*/
|
||||
public void setItemWriter(ItemWriter itemWriter) {
|
||||
this.itemWriter = itemWriter;
|
||||
}
|
||||
|
||||
public void setItemSkipPolicy(ItemSkipPolicy itemSkipPolicy) {
|
||||
this.itemSkipPolicy = itemSkipPolicy;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.launch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.ClearFailedException;
|
||||
import org.springframework.batch.item.FlushFailedException;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Mock {@link ItemWriter} that will throw an exception when a certain
|
||||
* number of items have been written.
|
||||
*/
|
||||
public class EmptyItemWriter implements ItemWriter, InitializingBean {
|
||||
|
||||
private boolean failed = false;
|
||||
|
||||
// point at which to fail...
|
||||
private int failurePoint = Integer.MAX_VALUE;
|
||||
|
||||
protected Log logger = LogFactory.getLog(EmptyItemWriter.class);
|
||||
|
||||
List list;
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
TransactionAwareProxyFactory factory = new TransactionAwareProxyFactory(new ArrayList());
|
||||
list = (List) factory.createInstance();
|
||||
}
|
||||
|
||||
public void setFailurePoint(int failurePoint) {
|
||||
this.failurePoint = failurePoint;
|
||||
}
|
||||
|
||||
public void write(Object data) {
|
||||
if (!failed && list.size() == failurePoint) {
|
||||
failed = true;
|
||||
throw new RuntimeException("Failed processing: [" + data + "]");
|
||||
}
|
||||
logger.info("Processing: [" + data + "]");
|
||||
list.add(data);
|
||||
}
|
||||
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void clear() throws ClearFailedException {
|
||||
//no-op
|
||||
}
|
||||
|
||||
public void flush() throws FlushFailedException {
|
||||
//no-op
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.launch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class SimpleJobLauncherTests extends TestCase {
|
||||
|
||||
private SimpleJobLauncher jobLauncher;
|
||||
|
||||
private MockControl repositoryControl = MockControl.createControl(JobRepository.class);
|
||||
|
||||
private Job job = new JobSupport("foo") {
|
||||
public void execute(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FINISHED);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
private JobParameters jobParameters = new JobParameters();
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
jobLauncher = new SimpleJobLauncher();
|
||||
jobRepository = (JobRepository) repositoryControl.getMock();
|
||||
jobLauncher.setJobRepository(jobRepository);
|
||||
|
||||
}
|
||||
|
||||
public void testRun() throws Exception {
|
||||
|
||||
JobExecution jobExecution = new JobExecution(null);
|
||||
|
||||
jobRepository.createJobExecution(job, jobParameters);
|
||||
repositoryControl.setReturnValue(jobExecution);
|
||||
|
||||
repositoryControl.replay();
|
||||
|
||||
jobLauncher.run(job, jobParameters);
|
||||
assertEquals(ExitStatus.FINISHED, jobExecution.getExitStatus());
|
||||
|
||||
repositoryControl.verify();
|
||||
}
|
||||
|
||||
public void testTaskExecutor() throws Exception {
|
||||
final List list = new ArrayList();
|
||||
jobLauncher.setTaskExecutor(new TaskExecutor() {
|
||||
public void execute(Runnable task) {
|
||||
list.add("execute");
|
||||
task.run();
|
||||
}
|
||||
});
|
||||
testRun();
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testRunWithException() throws Exception {
|
||||
job = new JobSupport() {
|
||||
public void execute(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
};
|
||||
try {
|
||||
testRun();
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals("foo", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testRunWithError() throws Exception {
|
||||
job = new JobSupport() {
|
||||
public void execute(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
throw new Error("foo");
|
||||
}
|
||||
};
|
||||
try {
|
||||
testRun();
|
||||
fail("Expected Error");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testInitialiseWithoutRepository() throws Exception {
|
||||
try {
|
||||
new SimpleJobLauncher().afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// expected
|
||||
assertTrue("Message did not contain repository: " + e.getMessage(), e.getMessage().toLowerCase().contains(
|
||||
"repository"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testInitialiseWithRepository() throws Exception {
|
||||
jobLauncher = new SimpleJobLauncher();
|
||||
jobLauncher.setJobRepository(jobRepository);
|
||||
jobLauncher.afterPropertiesSet(); // no error
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.launch.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier;
|
||||
import org.springframework.batch.execution.launch.JobLauncher;
|
||||
import org.springframework.batch.execution.launch.support.CommandLineJobRunner;
|
||||
import org.springframework.batch.execution.launch.support.SystemExiter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class CommandLineJobRunnerTests extends TestCase {
|
||||
|
||||
private static final String JOB = "org/springframework/batch/execution/bootstrap/support/job.xml";
|
||||
|
||||
private static final String JOB_NAME = "test-job";
|
||||
|
||||
private String jobPath = JOB;
|
||||
|
||||
private String jobName = JOB_NAME;
|
||||
|
||||
private String jobKey = "job.Key=myKey";
|
||||
|
||||
private String scheduleDate = "schedule.Date=01/23/2008";
|
||||
|
||||
private String vendorId = "vendor.id=33243243";
|
||||
|
||||
private String[] args = new String[] { jobPath, jobName, jobKey, scheduleDate, vendorId };
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
JobExecution jobExecution = new JobExecution(null, new Long(1));
|
||||
ExitStatus exitStatus = ExitStatus.FINISHED;
|
||||
jobExecution.setExitStatus(exitStatus);
|
||||
StubJobLauncher.jobExecution = jobExecution;
|
||||
StubExceptionClassifier.exception = null;
|
||||
}
|
||||
|
||||
public void testMain() {
|
||||
CommandLineJobRunner.main(args);
|
||||
assertEquals(0, StubSystemExiter.getStatus());
|
||||
}
|
||||
|
||||
public void testJobAlreadyRunning() {
|
||||
StubJobLauncher.throwExecutionRunningException = true;
|
||||
CommandLineJobRunner.main(args);
|
||||
assertTrue(StubExceptionClassifier.exception instanceof JobExecutionAlreadyRunningException);
|
||||
}
|
||||
|
||||
// can't test because it will cause the system to exit.
|
||||
// public void testInvalidArgs(){
|
||||
//
|
||||
// String[] args = new String[]{jobPath, jobName};
|
||||
// CommandLineJobRunner.main(args);
|
||||
// }
|
||||
|
||||
public void testWithNoParameters() throws Throwable {
|
||||
String[] args = new String[] { jobPath, jobName };
|
||||
CommandLineJobRunner.main(args);
|
||||
if (StubExceptionClassifier.exception != null) {
|
||||
throw StubExceptionClassifier.exception;
|
||||
}
|
||||
assertEquals(0, StubSystemExiter.status);
|
||||
assertEquals(new JobParameters(), StubJobLauncher.jobParameters);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
StubJobLauncher.tearDown();
|
||||
}
|
||||
|
||||
public static class StubSystemExiter implements SystemExiter {
|
||||
|
||||
public static int status;
|
||||
|
||||
public void exit(int status) {
|
||||
StubSystemExiter.status = status;
|
||||
}
|
||||
|
||||
public static int getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StubJobLauncher implements JobLauncher {
|
||||
|
||||
public static JobExecution jobExecution;
|
||||
|
||||
public static boolean throwExecutionRunningException = false;
|
||||
|
||||
public static JobParameters jobParameters;
|
||||
|
||||
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException {
|
||||
|
||||
StubJobLauncher.jobParameters = jobParameters;
|
||||
|
||||
if (throwExecutionRunningException) {
|
||||
throw new JobExecutionAlreadyRunningException("");
|
||||
}
|
||||
|
||||
return jobExecution;
|
||||
}
|
||||
|
||||
public static void tearDown() {
|
||||
jobExecution = null;
|
||||
throwExecutionRunningException = false;
|
||||
jobParameters = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StubExceptionClassifier implements ExitStatusExceptionClassifier {
|
||||
|
||||
public static Throwable exception;
|
||||
|
||||
public Object classify(Throwable throwable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getDefault() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ExitStatus classifyForExitCode(Throwable throwable) {
|
||||
exception = throwable;
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.launch.support;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.execution.launch.support.DefaultJobParametersFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DefaultJobParametersFactoryTests extends TestCase {
|
||||
|
||||
DefaultJobParametersFactory factory = new DefaultJobParametersFactory();
|
||||
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
|
||||
|
||||
public void testGetParameters() throws Exception {
|
||||
|
||||
String jobKey = "job.key=myKey";
|
||||
String scheduleDate = "schedule.date(date)=2008/01/23";
|
||||
String vendorId = "vendor.id(long)=33243243";
|
||||
|
||||
String[] args = new String[] { jobKey, scheduleDate, vendorId };
|
||||
|
||||
JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
assertNotNull(props);
|
||||
assertEquals("myKey", props.getString("job.key"));
|
||||
assertEquals(new Long(33243243L), props.getLong("vendor.id"));
|
||||
Date date = dateFormat.parse("01/23/2008");
|
||||
assertEquals(date, props.getDate("schedule.date"));
|
||||
}
|
||||
|
||||
public void testGetParametersWithDateFormat() throws Exception {
|
||||
|
||||
String[] args = new String[] { "schedule.date(date)=2008/23/01" };
|
||||
|
||||
factory.setDateFormat(new SimpleDateFormat("yyyy/dd/MM"));
|
||||
JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
assertNotNull(props);
|
||||
Date date = dateFormat.parse("01/23/2008");
|
||||
assertEquals(date, props.getDate("schedule.date"));
|
||||
}
|
||||
|
||||
public void testGetParametersWithBogusDate() throws Exception {
|
||||
|
||||
String[] args = new String[] { "schedule.date(date)=20080123" };
|
||||
|
||||
try {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong date: "+message, message.contains("20080123"));
|
||||
assertTrue("Message should contain format: "+message, message.contains("yyyy/MM/dd"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetParametersWithNumberFormat() throws Exception {
|
||||
|
||||
String[] args = new String[] { "value(long)=1,000" };
|
||||
|
||||
factory.setNumberFormat(new DecimalFormat("#,###"));
|
||||
JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
assertNotNull(props);
|
||||
assertEquals(1000L, props.getLong("value").longValue());
|
||||
}
|
||||
|
||||
public void testGetParametersWithBogusLong() throws Exception {
|
||||
|
||||
String[] args = new String[] { "value(long)=foo" };
|
||||
|
||||
try {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong number: "+message, message.contains("foo"));
|
||||
assertTrue("Message should contain format: "+message, message.contains("#"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetParametersWithDouble() throws Exception {
|
||||
|
||||
String[] args = new String[] { "value(long)=1.03" };
|
||||
factory.setNumberFormat(new DecimalFormat("#.#"));
|
||||
|
||||
try {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong number: "+message, message.contains("1.03"));
|
||||
assertTrue("Message should contain 'decimal': "+message, message.contains("decimal"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetProperties() throws Exception {
|
||||
|
||||
JobParameters parameters = new JobParametersBuilder().addDate("schedule.date", dateFormat.parse("01/23/2008"))
|
||||
.addString("job.key", "myKey").addLong("vendor.id", new Long(33243243)).toJobParameters();
|
||||
|
||||
Properties props = factory.getProperties(parameters);
|
||||
assertNotNull(props);
|
||||
assertEquals("myKey", props.getProperty("job.key"));
|
||||
assertEquals("33243243", props.getProperty("vendor.id(long)"));
|
||||
assertEquals("2008/01/23", props.getProperty("schedule.date(date)"));
|
||||
}
|
||||
|
||||
public void testEmptyArgs() {
|
||||
|
||||
JobParameters props = factory.getJobParameters(new Properties());
|
||||
assertTrue(props.getParameters().isEmpty());
|
||||
}
|
||||
|
||||
public void testNullArgs(){
|
||||
assertEquals(new JobParameters(), factory.getJobParameters(null));
|
||||
assertEquals(new Properties(), factory.getProperties(null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.launch.support;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.execution.launch.support.ScheduledJobParametersFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class ScheduledJobParametersFactoryTests extends TestCase {
|
||||
|
||||
ScheduledJobParametersFactory factory;
|
||||
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
factory = new ScheduledJobParametersFactory();
|
||||
}
|
||||
|
||||
public void testGetParameters() throws Exception {
|
||||
|
||||
String jobKey = "job.key=myKey";
|
||||
String scheduleDate = "schedule.date=2008/01/23";
|
||||
String vendorId = "vendor.id=33243243";
|
||||
|
||||
String[] args = new String[] { jobKey, scheduleDate, vendorId };
|
||||
|
||||
JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
assertNotNull(props);
|
||||
assertEquals("myKey", props.getString("job.key"));
|
||||
assertEquals("33243243", props.getString("vendor.id"));
|
||||
Date date = dateFormat.parse("01/23/2008");
|
||||
assertEquals(date, props.getDate("schedule.date"));
|
||||
}
|
||||
|
||||
public void testGetProperties() throws Exception {
|
||||
|
||||
JobParameters parameters = new JobParametersBuilder().addDate("schedule.date", dateFormat.parse("01/23/2008"))
|
||||
.addString("job.key", "myKey").addString("vendor.id", "33243243").toJobParameters();
|
||||
|
||||
Properties props = factory.getProperties(parameters);
|
||||
assertNotNull(props);
|
||||
assertEquals("myKey", props.getProperty("job.key"));
|
||||
assertEquals("33243243", props.getProperty("vendor.id"));
|
||||
assertEquals("2008/01/23", props.getProperty("schedule.date"));
|
||||
}
|
||||
|
||||
public void testEmptyArgs() {
|
||||
|
||||
JobParameters props = factory.getJobParameters(new Properties());
|
||||
assertTrue(props.getParameters().isEmpty());
|
||||
}
|
||||
|
||||
public void testNullArgs(){
|
||||
assertEquals(new JobParameters(), factory.getJobParameters(null));
|
||||
assertEquals(new Properties(), factory.getProperties(null));
|
||||
}
|
||||
|
||||
public void testGetParametersWithDateFormat() throws Exception {
|
||||
|
||||
String[] args = new String[] { "schedule.date=2008/23/01" };
|
||||
|
||||
factory.setDateFormat(new SimpleDateFormat("yyyy/dd/MM"));
|
||||
JobParameters props = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
assertNotNull(props);
|
||||
Date date = dateFormat.parse("01/23/2008");
|
||||
assertEquals(date, props.getDate("schedule.date"));
|
||||
}
|
||||
|
||||
public void testGetParametersWithBogusDate() throws Exception {
|
||||
|
||||
String[] args = new String[] { "schedule.date=20080123" };
|
||||
|
||||
try {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong date: "+message, message.contains("20080123"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.launch.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.runtime.JobParametersFactory;
|
||||
import org.springframework.batch.execution.configuration.MapJobRegistry;
|
||||
import org.springframework.batch.execution.configuration.ReferenceJobFactory;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.launch.JobLauncher;
|
||||
import org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
|
||||
private SimpleExportedJobLauncher launcher = new SimpleExportedJobLauncher();
|
||||
|
||||
private MapJobRegistry jobLocator;
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
launcher.setLauncher(new JobLauncher() {
|
||||
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException {
|
||||
JobExecution result = new JobExecution(null);
|
||||
StepExecution stepExecution = result.createStepExecution(new StepSupport("stepName"));
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
list.add(jobParameters);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
jobLocator = new MapJobRegistry();
|
||||
launcher.setJobLocator(jobLocator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
launcher = new SimpleExportedJobLauncher();
|
||||
try {
|
||||
launcher.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'launcher': " + message, message.toLowerCase().contains("joblauncher"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAfterPropertiesSetWithLauncher() throws Exception {
|
||||
launcher = new SimpleExportedJobLauncher();
|
||||
launcher.setLauncher(new JobLauncher() {
|
||||
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
launcher.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'locator': " + message, message.toLowerCase().contains("joblocator"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
*/
|
||||
public void testGetStatistics() {
|
||||
Properties props = launcher.getStatistics();
|
||||
assertNotNull(props);
|
||||
assertEquals(0, props.entrySet().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetStatisticsWithContent() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
launcher.run("foo");
|
||||
Properties props = launcher.getStatistics();
|
||||
assertNotNull(props);
|
||||
assertEquals(1, props.entrySet().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testIsRunning() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
launcher.run("foo");
|
||||
assertTrue(launcher.isRunning());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAlreadyRunning() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
launcher.setLauncher(new JobLauncher() {
|
||||
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException {
|
||||
throw new JobExecutionAlreadyRunningException("Bad!");
|
||||
}
|
||||
});
|
||||
String value = launcher.run("foo");
|
||||
assertTrue("Return value was not an exception: " + value, value.contains("JobExecutionAlreadyRunningException"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#run(java.lang.String)}.
|
||||
*/
|
||||
public void testRunNonExistentJob() {
|
||||
String value = launcher.run("foo");
|
||||
assertTrue("Return value was not an exception: " + value, value.contains("NoSuchJobException"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#run(java.lang.String)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testRunJobWithParameters() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
String value = launcher.run("foo", "bar=spam,bucket=crap");
|
||||
assertTrue(launcher.isRunning());
|
||||
assertTrue("Return value was not a JobExecution: " + value, value.contains("JobExecution"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#run(java.lang.String)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testRunJobWithParametersAndFactory() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
launcher.setJobParametersFactory(new JobParametersFactory() {
|
||||
public JobParameters getJobParameters(Properties properties) {
|
||||
return new JobParametersBuilder().addString("foo", "spam").toJobParameters();
|
||||
}
|
||||
public Properties getProperties(JobParameters params) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
launcher.run("foo", "bar=spam,bucket=crap");
|
||||
assertEquals(1, list.size());
|
||||
assertEquals("spam", ((JobParameters) list.get(0)).getString("foo"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.launch.support.SimpleExportedJobLauncher#stop()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testStop() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
launcher.run("foo");
|
||||
assertTrue(launcher.isRunning());
|
||||
launcher.stop();
|
||||
assertFalse(launcher.isRunning());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.launch.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.execution.launch.support.ExitCodeMapper;
|
||||
import org.springframework.batch.execution.launch.support.SimpleJvmExitCodeMapper;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
public class SimpleJvmExitCodeMapperTests extends TestCase {
|
||||
|
||||
private SimpleJvmExitCodeMapper ecm;
|
||||
private SimpleJvmExitCodeMapper ecm2;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
ecm = new SimpleJvmExitCodeMapper();
|
||||
Map ecmMap = new HashMap();
|
||||
ecmMap.put("MY_CUSTOM_CODE", new Integer(3));
|
||||
ecm.setMapping(ecmMap);
|
||||
|
||||
ecm2 = new SimpleJvmExitCodeMapper();
|
||||
Map ecm2Map = new HashMap();
|
||||
ecm2Map.put(ExitStatus.FINISHED.getExitCode(), new Integer(-1));
|
||||
ecm2Map.put(ExitStatus.FAILED.getExitCode(), new Integer(-2));
|
||||
ecm2Map.put(ExitCodeMapper.JOB_NOT_PROVIDED, new Integer(-3));
|
||||
ecm2Map.put(ExitCodeMapper.NO_SUCH_JOB, new Integer(-3));
|
||||
ecm2.setMapping(ecm2Map);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testGetExitCodeWithpPredefinedCodes() {
|
||||
assertEquals(
|
||||
ecm.getExitCode(ExitStatus.FINISHED.getExitCode()),
|
||||
ExitCodeMapper.JVM_EXITCODE_COMPLETED);
|
||||
assertEquals(
|
||||
ecm.getExitCode(ExitStatus.FAILED.getExitCode()),
|
||||
ExitCodeMapper.JVM_EXITCODE_GENERIC_ERROR);
|
||||
assertEquals(
|
||||
ecm.getExitCode(ExitCodeMapper.JOB_NOT_PROVIDED),
|
||||
ExitCodeMapper.JVM_EXITCODE_JOB_ERROR);
|
||||
assertEquals(
|
||||
ecm.getExitCode(ExitCodeMapper.NO_SUCH_JOB),
|
||||
ExitCodeMapper.JVM_EXITCODE_JOB_ERROR);
|
||||
}
|
||||
|
||||
public void testGetExitCodeWithPredefinedCodesOverridden() {
|
||||
System.out.println(ecm2.getExitCode(ExitStatus.FINISHED.getExitCode()));
|
||||
assertEquals(
|
||||
ecm2.getExitCode(ExitStatus.FINISHED.getExitCode()), -1);
|
||||
assertEquals(
|
||||
ecm2.getExitCode(ExitStatus.FAILED.getExitCode()), -2);
|
||||
assertEquals(
|
||||
ecm2.getExitCode(ExitCodeMapper.JOB_NOT_PROVIDED), -3);
|
||||
assertEquals(
|
||||
ecm2.getExitCode(ExitCodeMapper.NO_SUCH_JOB), -3);
|
||||
}
|
||||
|
||||
public void testGetExitCodeWithCustomCode() {
|
||||
assertEquals(ecm.getExitCode("MY_CUSTOM_CODE"),3);
|
||||
}
|
||||
|
||||
public void testGetExitCodeWithDefaultCode() {
|
||||
assertEquals(
|
||||
ecm.getExitCode("UNDEFINED_CUSTOM_CODE"),
|
||||
ExitCodeMapper.JVM_EXITCODE_GENERIC_ERROR);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.batch.execution.launch.support;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.execution.launch.JobLauncher;
|
||||
|
||||
/**
|
||||
* Mock Job Launcher. Normally, something like EasyMock would
|
||||
* be used to mock an interface, however, because of the nature
|
||||
* of launching a batch job from the command line, the mocked
|
||||
* class cannot be injected.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class StubJobLauncher implements JobLauncher {
|
||||
|
||||
public static final int RUN_NO_ARGS = 0;
|
||||
public static final int RUN_JOB_NAME = 1;
|
||||
public static final int RUN_JOB_IDENTIFIER =2 ;
|
||||
|
||||
private int lastRunCalled = RUN_NO_ARGS;
|
||||
private JobExecution returnValue = null;
|
||||
|
||||
private boolean isRunning = false;
|
||||
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
public JobExecution run(Job job, JobParameters jobParameters)
|
||||
throws JobExecutionAlreadyRunningException {
|
||||
lastRunCalled = RUN_JOB_IDENTIFIER;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
public void setReturnValue(JobExecution returnValue){
|
||||
this.returnValue = returnValue;
|
||||
}
|
||||
|
||||
public void setIsRunning(boolean isRunning){
|
||||
this.isRunning = isRunning;
|
||||
}
|
||||
|
||||
public int getLastRunCalled(){
|
||||
return lastRunCalled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.listener;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.ChunkListener;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class CompositeChunkListenerTests extends TestCase {
|
||||
|
||||
MockControl listenerControl = MockControl.createControl(ChunkListener.class);
|
||||
|
||||
ChunkListener listener;
|
||||
CompositeChunkListener compositeListener;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
listener = (ChunkListener)listenerControl.getMock();
|
||||
compositeListener = new CompositeChunkListener();
|
||||
compositeListener.register(listener);
|
||||
}
|
||||
|
||||
public void testBeforeChunk(){
|
||||
|
||||
listener.beforeChunk();
|
||||
listenerControl.replay();
|
||||
compositeListener.beforeChunk();
|
||||
listenerControl.verify();
|
||||
}
|
||||
|
||||
public void testAfterChunk(){
|
||||
|
||||
listener.afterChunk();
|
||||
listenerControl.replay();
|
||||
compositeListener.afterChunk();
|
||||
listenerControl.verify();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.listener;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.ItemReadListener;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class CompositeItemReadListenerTests extends TestCase {
|
||||
|
||||
MockControl listenerControl = MockControl.createControl(ItemReadListener.class);
|
||||
|
||||
ItemReadListener listener;
|
||||
CompositeItemReadListener compositeListener;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
listener = (ItemReadListener)listenerControl.getMock();
|
||||
compositeListener = new CompositeItemReadListener();
|
||||
compositeListener.register(listener);
|
||||
}
|
||||
|
||||
public void testBeforeRead(){
|
||||
|
||||
listener.beforeRead();
|
||||
listenerControl.replay();
|
||||
compositeListener.beforeRead();
|
||||
listenerControl.verify();
|
||||
}
|
||||
|
||||
public void testAfterRead(){
|
||||
Object item = new Object();
|
||||
listener.afterRead(item);
|
||||
listenerControl.replay();
|
||||
compositeListener.afterRead(item);
|
||||
listenerControl.verify();
|
||||
}
|
||||
|
||||
public void testOnReadError(){
|
||||
|
||||
Exception ex = new Exception();
|
||||
listener.onReadError(ex);
|
||||
listenerControl.replay();
|
||||
compositeListener.onReadError(ex);
|
||||
listenerControl.verify();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.listener;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.ItemWriteListener;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class CompositeItemWriteListenerTests extends TestCase {
|
||||
|
||||
MockControl listenerControl = MockControl.createControl(ItemWriteListener.class);
|
||||
|
||||
ItemWriteListener listener;
|
||||
CompositeItemWriteListener compositeListener;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
listener = (ItemWriteListener)listenerControl.getMock();
|
||||
compositeListener = new CompositeItemWriteListener();
|
||||
compositeListener.register(listener);
|
||||
}
|
||||
|
||||
public void testBeforeWrite(){
|
||||
Object item = new Object();
|
||||
listener.beforeWrite(item);
|
||||
listenerControl.replay();
|
||||
compositeListener.beforeWrite(item);
|
||||
listenerControl.verify();
|
||||
}
|
||||
|
||||
public void testAfterWrite(){
|
||||
listener.afterWrite();
|
||||
listenerControl.replay();
|
||||
compositeListener.afterWrite();
|
||||
listenerControl.verify();
|
||||
}
|
||||
|
||||
public void testOnWriteError(){
|
||||
Object item = new Object();
|
||||
Exception ex = new Exception();
|
||||
listener.onWriteError(ex, item);
|
||||
listenerControl.replay();
|
||||
compositeListener.onWriteError(ex, item);
|
||||
listenerControl.verify();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.listener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobListener;
|
||||
import org.springframework.batch.core.listener.JobListenerSupport;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.listener.CompositeJobListener;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class CompositeJobListenerTests extends TestCase {
|
||||
|
||||
private CompositeJobListener listener = new CompositeJobListener();
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeJobListener#setListeners(org.springframework.batch.core.JobListener[])}.
|
||||
*/
|
||||
public void testSetListeners() {
|
||||
listener.setListeners(new JobListener[] { new JobListenerSupport() {
|
||||
public void afterJob(JobExecution jobExecution) {
|
||||
list.add("fail");
|
||||
}
|
||||
}, new JobListenerSupport() {
|
||||
public void afterJob(JobExecution jobExecution) {
|
||||
list.add("continue");
|
||||
}
|
||||
} });
|
||||
listener.afterJob(null);
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeJobListener#registerListener(org.springframework.batch.core.JobListener)}.
|
||||
*/
|
||||
public void testSetListener() {
|
||||
listener.register(new JobListenerSupport() {
|
||||
public void afterJob(JobExecution jobExecution) {
|
||||
list.add("fail");
|
||||
}
|
||||
});
|
||||
listener.afterJob(null);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeJobListener#beforeJob(JobExecution)}.
|
||||
*/
|
||||
public void testOpen() {
|
||||
listener.register(new JobListenerSupport() {
|
||||
public void beforeJob(JobExecution stepExecution) {
|
||||
list.add("foo");
|
||||
}
|
||||
});
|
||||
listener.beforeJob(new JobExecution(new JobInstance(new Long(11L), null, new JobSupport())));
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.listener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepListener;
|
||||
import org.springframework.batch.core.listener.StepListenerSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class CompositeStepListenerTests extends TestCase {
|
||||
|
||||
private CompositeStepListener listener = new CompositeStepListener();
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeStepListener#setListeners(org.springframework.batch.core.StepListener[])}.
|
||||
*/
|
||||
public void testSetListeners() {
|
||||
listener.setListeners(new StepListener[] { new StepListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("fail");
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
}, new StepListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("continue");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
} });
|
||||
assertFalse(listener.afterStep(null).isContinuable());
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeStepListener#registerListener(org.springframework.batch.core.StepListener)}.
|
||||
*/
|
||||
public void testSetListener() {
|
||||
listener.register(new StepListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("fail");
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
});
|
||||
assertFalse(listener.afterStep(null).isContinuable());
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeStepListener#beforeStep(StepExecution)}.
|
||||
*/
|
||||
public void testOpen() {
|
||||
listener.register(new StepListenerSupport() {
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
list.add("foo");
|
||||
}
|
||||
});
|
||||
listener.beforeStep(new StepExecution(new StepSupport("foo"), null));
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.listener.CompositeStepListener#beforeStep(StepExecution)}.
|
||||
*/
|
||||
public void testOnError() {
|
||||
listener.register(new StepListenerSupport() {
|
||||
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
|
||||
list.add("foo");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
listener.onErrorInStep(null, new RuntimeException());
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.repository;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JobRepositoryFactoryBeanTests extends TestCase{
|
||||
|
||||
JobRepositoryFactoryBean factory;
|
||||
MockControl incrementerControl = MockControl.createControl(DataFieldMaxValueIncrementerFactory.class);
|
||||
DataFieldMaxValueIncrementerFactory incrementerFactory;
|
||||
DataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
factory = new JobRepositoryFactoryBean();
|
||||
MockControl dataSourceControl = MockControl.createControl(DataSource.class);
|
||||
dataSource = (DataSource)dataSourceControl.getMock();
|
||||
factory.setDataSource(dataSource);
|
||||
incrementerFactory = (DataFieldMaxValueIncrementerFactory)incrementerControl.getMock();
|
||||
factory.setIncrementerFactory(incrementerFactory);
|
||||
}
|
||||
|
||||
public void testNoDatabaseType() throws Exception{
|
||||
|
||||
try{
|
||||
factory.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch(IllegalArgumentException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testInvalidDatabaseType() throws Exception{
|
||||
|
||||
factory.setDatabaseType("invalid type");
|
||||
try{
|
||||
factory.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch(IllegalArgumentException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreateRepository() throws Exception{
|
||||
String databaseType = "databaseType";
|
||||
factory.setDatabaseType(databaseType);
|
||||
|
||||
incrementerFactory.getIncrementer(databaseType, "BATCH_JOB_SEQ");
|
||||
incrementerControl.setReturnValue(new StubIncrementer());
|
||||
incrementerFactory.getIncrementer(databaseType, "BATCH_JOB_EXECUTION_SEQ");
|
||||
incrementerControl.setReturnValue(new StubIncrementer());
|
||||
incrementerFactory.getIncrementer(databaseType, "BATCH_STEP_EXECUTION_SEQ");
|
||||
incrementerControl.setReturnValue(new StubIncrementer());
|
||||
incrementerControl.replay();
|
||||
|
||||
factory.getObject();
|
||||
|
||||
incrementerControl.verify();
|
||||
}
|
||||
|
||||
private class StubIncrementer implements DataFieldMaxValueIncrementer {
|
||||
|
||||
public int nextIntValue() throws DataAccessException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long nextLongValue() throws DataAccessException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String nextStringValue() throws DataAccessException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.repository.dao.StepExecutionDao;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
|
||||
public class MockStepDao implements StepExecutionDao {
|
||||
|
||||
private List newSteps;
|
||||
|
||||
public List findStepInstances(JobInstance job) {
|
||||
return newSteps;
|
||||
}
|
||||
|
||||
public void saveStepExecution(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
public void updateStepExecution(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
public void setStepsToReturnOnCreate(List steps) {
|
||||
this.newSteps = steps;
|
||||
}
|
||||
|
||||
public ExecutionContext findExecutionContext(StepExecution stepExecution) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
public StepExecution getStepExecution(JobExecution jobExecution, Step step) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package org.springframework.batch.execution.repository;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Repository tests using JDBC DAOs (rather than mocks).
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class SimpleJobRepositoryIntegrationTests extends AbstractTransactionalDataSourceSpringContextTests {
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { ClassUtils.addResourcePathToPackagePath(getClass(), "dao/sql-dao-test.xml") };
|
||||
}
|
||||
|
||||
private SimpleJobRepository jobRepository;
|
||||
|
||||
private JobSupport job = new JobSupport("testJob");
|
||||
|
||||
private JobParameters jobParameters = new JobParameters();
|
||||
|
||||
public void setJobRepository(SimpleJobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create two job executions for same job+parameters tuple. Check both
|
||||
* executions belong to the same job instance and job.
|
||||
*/
|
||||
public void testCreateAndFind() throws Exception {
|
||||
|
||||
job.setRestartable(true);
|
||||
|
||||
Map stringParams = new HashMap() {
|
||||
{
|
||||
put("stringKey", "stringValue");
|
||||
}
|
||||
};
|
||||
Map longParams = new HashMap() {
|
||||
{
|
||||
put("longKey", new Long(1));
|
||||
}
|
||||
};
|
||||
Map doubleParams = new HashMap() {
|
||||
{
|
||||
put("doubleKey", new Double(1.1));
|
||||
}
|
||||
};
|
||||
Map dateParams = new HashMap() {
|
||||
{
|
||||
put("dateKey", new Date(1));
|
||||
}
|
||||
};
|
||||
JobParameters jobParams = new JobParameters(stringParams, longParams, doubleParams, dateParams);
|
||||
|
||||
JobExecution firstExecution = jobRepository.createJobExecution(job, jobParams);
|
||||
firstExecution.setStartTime(new Date());
|
||||
|
||||
assertEquals(job, firstExecution.getJobInstance().getJob());
|
||||
|
||||
jobRepository.saveOrUpdate(firstExecution);
|
||||
firstExecution.setEndTime(new Date());
|
||||
jobRepository.saveOrUpdate(firstExecution);
|
||||
JobExecution secondExecution = jobRepository.createJobExecution(job, jobParams);
|
||||
|
||||
assertEquals(firstExecution.getJobInstance(), secondExecution.getJobInstance());
|
||||
assertEquals(job, secondExecution.getJobInstance().getJob());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create two job executions for same job+parameters tuple. Check both
|
||||
* executions belong to the same job instance and job.
|
||||
*/
|
||||
public void testCreateAndFindWithNoStartDate() throws Exception {
|
||||
job.setRestartable(true);
|
||||
|
||||
JobExecution firstExecution = jobRepository.createJobExecution(job, jobParameters);
|
||||
firstExecution.setEndTime(new Date());
|
||||
jobRepository.saveOrUpdate(firstExecution);
|
||||
JobExecution secondExecution = jobRepository.createJobExecution(job, jobParameters);
|
||||
|
||||
assertEquals(firstExecution.getJobInstance(), secondExecution.getJobInstance());
|
||||
assertEquals(job, secondExecution.getJobInstance().getJob());
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-restartable JobInstance can be run only once - attempt to run
|
||||
* existing non-restartable JobInstance causes error.
|
||||
*/
|
||||
public void testRunNonRestartableJobInstanceTwice() throws Exception {
|
||||
job.setRestartable(false);
|
||||
|
||||
JobExecution firstExecution = jobRepository.createJobExecution(job, jobParameters);
|
||||
jobRepository.saveOrUpdate(firstExecution);
|
||||
|
||||
try {
|
||||
jobRepository.createJobExecution(job, jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (JobRestartException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save multiple StepExecutions for the same step and check the returned
|
||||
* count and last execution are correct.
|
||||
*/
|
||||
public void testGetStepExecutionCountAndLastStepExecution() throws Exception {
|
||||
job.setRestartable(true);
|
||||
StepSupport step = new StepSupport("restartedStep");
|
||||
|
||||
// first execution
|
||||
JobExecution firstJobExec = jobRepository.createJobExecution(job, jobParameters);
|
||||
StepExecution firstStepExec = new StepExecution(step, firstJobExec);
|
||||
jobRepository.saveOrUpdate(firstJobExec);
|
||||
jobRepository.saveOrUpdate(firstStepExec);
|
||||
|
||||
assertEquals(1, jobRepository.getStepExecutionCount(firstJobExec.getJobInstance(), step));
|
||||
assertEquals(firstStepExec, jobRepository.getLastStepExecution(firstJobExec.getJobInstance(), step));
|
||||
|
||||
// first execution failed
|
||||
firstJobExec.setStartTime(new Date(4));
|
||||
firstStepExec.setStartTime(new Date(5));
|
||||
firstStepExec.setStatus(BatchStatus.FAILED);
|
||||
firstStepExec.setEndTime(new Date(6));
|
||||
jobRepository.saveOrUpdate(firstStepExec);
|
||||
firstJobExec.setStatus(BatchStatus.FAILED);
|
||||
firstJobExec.setEndTime(new Date(7));
|
||||
jobRepository.saveOrUpdate(firstJobExec);
|
||||
|
||||
// second execution
|
||||
JobExecution secondJobExec = jobRepository.createJobExecution(job, jobParameters);
|
||||
StepExecution secondStepExec = new StepExecution(step, secondJobExec);
|
||||
jobRepository.saveOrUpdate(secondJobExec);
|
||||
jobRepository.saveOrUpdate(secondStepExec);
|
||||
|
||||
assertEquals(2, jobRepository.getStepExecutionCount(secondJobExec.getJobInstance(), step));
|
||||
assertEquals(secondStepExec, jobRepository.getLastStepExecution(secondJobExec.getJobInstance(), step));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save execution context and retrieve it.
|
||||
*/
|
||||
public void testSaveExecutionContext() throws Exception {
|
||||
ExecutionContext ctx = new ExecutionContext() {
|
||||
{
|
||||
putLong("crashedPosition", 7);
|
||||
}
|
||||
};
|
||||
JobExecution jobExec = jobRepository.createJobExecution(job, jobParameters);
|
||||
Step step = new StepSupport("step1");
|
||||
StepExecution stepExec = new StepExecution(step, jobExec);
|
||||
stepExec.setExecutionContext(ctx);
|
||||
|
||||
jobRepository.saveOrUpdate(stepExec);
|
||||
jobRepository.saveOrUpdateExecutionContext(stepExec);
|
||||
|
||||
StepExecution retrievedExec = jobRepository.getLastStepExecution(jobExec.getJobInstance(), step);
|
||||
assertEquals(stepExec, retrievedExec);
|
||||
assertEquals(ctx, retrievedExec.getExecutionContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* If JobExecution is already running, exception will be thrown in attempt
|
||||
* to create new execution.
|
||||
*/
|
||||
public void testOnlyOneJobExecutionAllowedRunning() throws Exception {
|
||||
job.setRestartable(true);
|
||||
jobRepository.createJobExecution(job, jobParameters);
|
||||
|
||||
try {
|
||||
jobRepository.createJobExecution(job, jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (JobExecutionAlreadyRunningException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.repository.dao.JobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.JobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.StepExecutionDao;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
|
||||
/**
|
||||
* Test SimpleJobRepository. The majority of test cases are tested using
|
||||
* EasyMock, however, there were some issues with using it for the stepExecutionDao when
|
||||
* testing finding or creating steps, so an actual mock class had to be written.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class SimpleJobRepositoryTests extends TestCase {
|
||||
|
||||
SimpleJobRepository jobRepository;
|
||||
|
||||
JobSupport jobConfiguration;
|
||||
|
||||
JobParameters jobParameters;
|
||||
|
||||
Step stepConfiguration1;
|
||||
|
||||
Step stepConfiguration2;
|
||||
|
||||
MockControl jobExecutionDaoControl = MockControl.createControl(JobExecutionDao.class);
|
||||
|
||||
MockControl jobInstanceDaoControl = MockControl.createControl(JobInstanceDao.class);
|
||||
|
||||
MockControl stepExecutionDaoControl = MockControl.createControl(StepExecutionDao.class);
|
||||
|
||||
JobExecutionDao jobExecutionDao;
|
||||
|
||||
JobInstanceDao jobInstanceDao;
|
||||
|
||||
StepExecutionDao stepExecutionDao;
|
||||
|
||||
MockStepDao mockStepDao = new MockStepDao();
|
||||
|
||||
JobInstance databaseJob;
|
||||
|
||||
String databaseStep1;
|
||||
|
||||
String databaseStep2;
|
||||
|
||||
List steps;
|
||||
|
||||
ExecutionContext executionContext;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
|
||||
jobExecutionDao = (JobExecutionDao) jobExecutionDaoControl.getMock();
|
||||
jobInstanceDao = (JobInstanceDao) jobInstanceDaoControl.getMock();
|
||||
stepExecutionDao = (StepExecutionDao) stepExecutionDaoControl.getMock();
|
||||
|
||||
jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao);
|
||||
|
||||
jobParameters = new JobParametersBuilder().toJobParameters();
|
||||
|
||||
jobConfiguration = new JobSupport();
|
||||
jobConfiguration.setBeanName("RepositoryTest");
|
||||
jobConfiguration.setRestartable(true);
|
||||
|
||||
stepConfiguration1 = new StepSupport("TestStep1");
|
||||
|
||||
stepConfiguration2 = new StepSupport("TestStep2");
|
||||
|
||||
List stepConfigurations = new ArrayList();
|
||||
stepConfigurations.add(stepConfiguration1);
|
||||
stepConfigurations.add(stepConfiguration2);
|
||||
|
||||
jobConfiguration.setSteps(stepConfigurations);
|
||||
|
||||
databaseJob = new JobInstance(new Long(1), jobParameters, jobConfiguration);
|
||||
|
||||
databaseStep1 = "dbStep1";
|
||||
databaseStep2 = "dbStep2";
|
||||
|
||||
steps = new ArrayList();
|
||||
steps.add(databaseStep1);
|
||||
steps.add(databaseStep2);
|
||||
|
||||
executionContext = new ExecutionContext();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test a restartable job, that has not been run before.
|
||||
*/
|
||||
public void testCreateRestartableJob() throws Exception {
|
||||
|
||||
// List jobExecutions = new ArrayList();
|
||||
//
|
||||
// jobInstanceDao.findJobInstances(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(jobExecutions);
|
||||
// jobInstanceDao.createJobInstance(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(databaseJob);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep1");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep1);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep2");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep2);
|
||||
// jobExecutionDao.saveJobExecution(new JobExecution(databaseJob));
|
||||
// jobExecutionDaoControl.setMatcher(new ArgumentsMatcher() {
|
||||
// public boolean matches(Object[] expected, Object[] actual) {
|
||||
// return ((JobExecution) actual[0]).getJobInstance().equals(databaseJob);
|
||||
// }
|
||||
//
|
||||
// public String toString(Object[] arguments) {
|
||||
// return "" + arguments[0];
|
||||
// }
|
||||
// });
|
||||
// stepExecutionDaoControl.replay();
|
||||
//// stepInstanceDaoControl.replay();
|
||||
// jobExecutionDaoControl.replay();
|
||||
// jobInstanceDaoControl.replay();
|
||||
// JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobParameters).getJobInstance();
|
||||
// assertTrue(job.equals(databaseJob));
|
||||
// List jobSteps = job.getStepNames();
|
||||
// Iterator it = jobSteps.iterator();
|
||||
// String step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep1));
|
||||
// step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep2));
|
||||
}
|
||||
|
||||
public void testRestartedJob() throws Exception {
|
||||
|
||||
// final List executions = new ArrayList();
|
||||
// JobExecution execution = databaseJob.createJobExecution();
|
||||
// executions.add(execution);
|
||||
// // For this test it is important that the execution is finished
|
||||
// // and the executions in the list contain one with an end date
|
||||
// execution.setEndTime(new Date(System.currentTimeMillis()));
|
||||
//
|
||||
// StepExecution databaseStep1Exec = new StepExecution(databaseStep1, execution, new Long(1));
|
||||
// StepExecution databaseStep2Exec = new StepExecution(databaseStep2, execution, new Long(2));
|
||||
//
|
||||
// List jobs = new ArrayList();
|
||||
// jobInstanceDao.findJobInstances(jobConfiguration.getName(), jobParameters);
|
||||
// jobs.add(databaseJob);
|
||||
// jobInstanceDaoControl.setReturnValue(jobs);
|
||||
//// stepInstanceDao.findStepInstance(databaseJob, "TestStep1");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep1);
|
||||
//// stepExecutionDao.getLastStepExecution(databaseStep1, jobExecution);
|
||||
//// stepExecutionDaoControl.setReturnValue(databaseStep1Exec);
|
||||
// stepExecutionDao.findExecutionContext(databaseStep1Exec);
|
||||
// stepExecutionDaoControl.setReturnValue(executionContext);
|
||||
// //stepExecutionDao.getStepExecutionCount(databaseStep1);
|
||||
//// stepExecutionDaoControl.setReturnValue(1);
|
||||
//// stepInstanceDao.findStepInstance(databaseJob, "TestStep2");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep2);
|
||||
//// stepExecutionDao.getLastStepExecution(databaseStep2, jobExecution);
|
||||
//// stepExecutionDaoControl.setReturnValue(databaseStep2Exec);
|
||||
// stepExecutionDao.findExecutionContext(databaseStep2Exec);
|
||||
// stepExecutionDaoControl.setReturnValue(executionContext);
|
||||
//// stepExecutionDao.getStepExecutionCount(databaseStep2);
|
||||
//// stepExecutionDaoControl.setReturnValue(1);
|
||||
// stepExecutionDaoControl.replay();
|
||||
//// stepInstanceDaoControl.replay();
|
||||
// jobExecutionDao.getJobExecutionCount(databaseJob);
|
||||
// jobExecutionDaoControl.setReturnValue(1);
|
||||
// jobExecutionDao.findJobExecutions(databaseJob);
|
||||
// jobExecutionDaoControl.setReturnValue(executions);
|
||||
// jobExecutionDao.saveJobExecution(new JobExecution(databaseJob));
|
||||
// jobExecutionDaoControl.setMatcher(new ArgumentsMatcher() {
|
||||
// public boolean matches(Object[] expected, Object[] actual) {
|
||||
// JobExecution execution = (JobExecution) actual[0];
|
||||
// return execution.getJobInstance().equals(databaseJob);
|
||||
// }
|
||||
//
|
||||
// public String toString(Object[] arguments) {
|
||||
// return "" + arguments[0];
|
||||
// }
|
||||
// });
|
||||
// jobExecutionDaoControl.setVoidCallable();
|
||||
// jobExecutionDaoControl.replay();
|
||||
// jobInstanceDaoControl.replay();
|
||||
// JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobParameters).getJobInstance();
|
||||
// assertTrue(job.equals(databaseJob));
|
||||
// List jobSteps = job.getStepNames();
|
||||
// Iterator it = jobSteps.iterator();
|
||||
// String step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep1));
|
||||
//// assertTrue(step.getStepExecutionCount() == 1);
|
||||
// step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep2));
|
||||
//// assertTrue(step.getStepExecutionCount() == 1);
|
||||
}
|
||||
|
||||
public void testCreateNonRestartableJob() throws Exception {
|
||||
|
||||
// List jobs = new ArrayList();
|
||||
// jobConfiguration.setRestartable(false);
|
||||
//
|
||||
// jobInstanceDao.findJobInstances(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(jobs);
|
||||
// jobInstanceDao.createJobInstance(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(databaseJob);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep1");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep1);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep2");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep2);
|
||||
// jobExecutionDao.saveJobExecution(new JobExecution(databaseJob));
|
||||
// jobExecutionDaoControl.setMatcher(new ArgumentsMatcher() {
|
||||
// public boolean matches(Object[] expected, Object[] actual) {
|
||||
// return ((JobExecution) actual[0]).getJobInstance().equals(databaseJob);
|
||||
// }
|
||||
//
|
||||
// public String toString(Object[] arguments) {
|
||||
// return "" + arguments[0];
|
||||
// }
|
||||
// });
|
||||
// stepExecutionDaoControl.replay();
|
||||
//// stepInstanceDaoControl.replay();
|
||||
// jobExecutionDaoControl.replay();
|
||||
// jobInstanceDaoControl.replay();
|
||||
// JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobParameters).getJobInstance();
|
||||
// assertTrue(job.equals(databaseJob));
|
||||
// List jobSteps = job.getStepNames();
|
||||
// Iterator it = jobSteps.iterator();
|
||||
// String step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep1));
|
||||
// step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep2));
|
||||
}
|
||||
|
||||
|
||||
public void testSaveOrUpdateInvalidJobExecution() {
|
||||
|
||||
// failure scenario - must have job ID
|
||||
JobExecution jobExecution = new JobExecution(null);
|
||||
try {
|
||||
jobRepository.saveOrUpdate(jobExecution);
|
||||
fail();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testSaveOrUpdateValidJobExecution() throws Exception {
|
||||
|
||||
JobExecution jobExecution = new JobExecution(new JobInstance(new Long(1), jobParameters, jobConfiguration));
|
||||
|
||||
// new execution - call save on job dao
|
||||
jobExecutionDao.saveJobExecution(jobExecution);
|
||||
jobExecutionDaoControl.replay();
|
||||
jobRepository.saveOrUpdate(jobExecution);
|
||||
jobExecutionDaoControl.reset();
|
||||
|
||||
// update existing execution
|
||||
jobExecution.setId(new Long(5));
|
||||
jobExecutionDao.updateJobExecution(jobExecution);
|
||||
jobExecutionDaoControl.replay();
|
||||
jobRepository.saveOrUpdate(jobExecution);
|
||||
}
|
||||
|
||||
public void testSaveOrUpdateStepExecutionException() {
|
||||
|
||||
StepExecution stepExecution = new StepExecution(new StepSupport("stepName"), null, null);
|
||||
|
||||
// failure scenario -- no step id set.
|
||||
try {
|
||||
jobRepository.saveOrUpdate(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test to ensure that if a StepDao returns invalid restart data, it is
|
||||
* corrected.
|
||||
*/
|
||||
public void testCreateStepsFixesInvalidExecutionContext() throws Exception {
|
||||
|
||||
// List jobs = new ArrayList();
|
||||
//
|
||||
// jobInstanceDao.findJobInstances(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(jobs);
|
||||
// jobInstanceDao.createJobInstance(jobConfiguration.getName(), jobParameters);
|
||||
// jobInstanceDaoControl.setReturnValue(databaseJob);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep1");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep1);
|
||||
//// stepInstanceDao.createStepInstance(databaseJob, "TestStep2");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep2);
|
||||
// jobExecutionDao.saveJobExecution(new JobExecution(databaseJob));
|
||||
// jobExecutionDaoControl.setMatcher(new ArgumentsMatcher() {
|
||||
// public boolean matches(Object[] expected, Object[] actual) {
|
||||
// return ((JobExecution) actual[0]).getJobInstance().equals(databaseJob);
|
||||
// }
|
||||
//
|
||||
// public String toString(Object[] arguments) {
|
||||
// return "" + arguments[0];
|
||||
// }
|
||||
// });
|
||||
// stepExecutionDaoControl.replay();
|
||||
//// stepInstanceDaoControl.replay();
|
||||
// jobExecutionDaoControl.replay();
|
||||
// jobInstanceDaoControl.replay();
|
||||
// JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobParameters).getJobInstance();
|
||||
// List jobSteps = job.getStepNames();
|
||||
// Iterator it = jobSteps.iterator();
|
||||
// String step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep1));
|
||||
// step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep2));
|
||||
}
|
||||
|
||||
public void testFindStepsFixesInvalidExecutionContext() throws Exception {
|
||||
|
||||
// StepExecution databaseStep1Exec = new StepExecution(databaseStep1, null, new Long(1));
|
||||
// StepExecution databaseStep2Exec = new StepExecution(databaseStep2, null, new Long(2));
|
||||
//
|
||||
// List jobs = new ArrayList();
|
||||
// jobInstanceDao.findJobInstances(jobConfiguration.getName(), jobParameters);
|
||||
// jobs.add(databaseJob);
|
||||
// jobInstanceDaoControl.setReturnValue(jobs);
|
||||
//// stepInstanceDao.findStepInstance(databaseJob, "TestStep1");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep1);
|
||||
//// stepExecutionDao.getLastStepExecution(databaseStep1, null);
|
||||
//// stepExecutionDaoControl.setReturnValue(databaseStep1Exec);
|
||||
// stepExecutionDao.findExecutionContext(databaseStep1Exec);
|
||||
// stepExecutionDaoControl.setReturnValue(executionContext);
|
||||
//// stepExecutionDao.getStepExecutionCount(databaseStep1);
|
||||
//// stepExecutionDaoControl.setReturnValue(1);
|
||||
//// stepInstanceDao.findStepInstance(databaseJob, "TestStep2");
|
||||
//// stepInstanceDaoControl.setReturnValue(databaseStep2);
|
||||
//// stepExecutionDao.getLastStepExecution(databaseStep2, null);
|
||||
//// stepExecutionDaoControl.setReturnValue(databaseStep2Exec);
|
||||
// stepExecutionDao.findExecutionContext(databaseStep2Exec);
|
||||
// stepExecutionDaoControl.setReturnValue(executionContext);
|
||||
//// stepExecutionDao.getStepExecutionCount(databaseStep2);
|
||||
//// stepExecutionDaoControl.setReturnValue(1);
|
||||
// stepExecutionDaoControl.replay();
|
||||
//// stepInstanceDaoControl.replay();
|
||||
//
|
||||
// jobExecutionDao.getJobExecutionCount(databaseJob);
|
||||
// jobExecutionDaoControl.setReturnValue(1);
|
||||
// jobExecutionDao.findJobExecutions(databaseJob);
|
||||
// jobExecutionDaoControl.setReturnValue(new ArrayList());
|
||||
// jobExecutionDao.saveJobExecution(new JobExecution(databaseJob));
|
||||
// jobExecutionDaoControl.setMatcher(new ArgumentsMatcher() {
|
||||
// public boolean matches(Object[] expected, Object[] actual) {
|
||||
// return ((JobExecution) actual[0]).getJobInstance().equals(databaseJob);
|
||||
// }
|
||||
//
|
||||
// public String toString(Object[] arguments) {
|
||||
// return "" + arguments[0];
|
||||
// }
|
||||
// });
|
||||
// jobExecutionDaoControl.replay();
|
||||
// jobInstanceDaoControl.replay();
|
||||
// JobInstance job = jobRepository.createJobExecution(jobConfiguration, jobParameters).getJobInstance();
|
||||
// assertTrue(job.equals(databaseJob));
|
||||
// List jobSteps = job.getStepNames();
|
||||
// Iterator it = jobSteps.iterator();
|
||||
// String step = (String) it.next();
|
||||
// assertTrue(step.equals(databaseStep1));
|
||||
//// assertTrue(step.getLastExecution().getExecutionContext().isEmpty());
|
||||
// step = (String) it.next();
|
||||
//// assertTrue(step.getLastExecution().getExecutionContext().isEmpty());
|
||||
// assertTrue(step.equals(databaseStep2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractJobDaoTests extends AbstractTransactionalDataSourceSpringContextTests {
|
||||
|
||||
protected JobInstanceDao jobInstanceDao;
|
||||
|
||||
protected JobExecutionDao jobExecutionDao;
|
||||
|
||||
protected JobParameters jobParameters = new JobParametersBuilder().addString("job.key", "jobKey").addLong("long",
|
||||
new Long(1)).addDate("date", new Date(7)).addDouble("double", new Double(7.7)).toJobParameters();
|
||||
|
||||
protected JobInstance jobInstance;
|
||||
|
||||
protected Job job;
|
||||
|
||||
protected JobExecution jobExecution;
|
||||
|
||||
protected Date jobExecutionStartTime = new Date(System.currentTimeMillis());
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { ClassUtils.addResourcePathToPackagePath(getClass(), "sql-dao-test.xml") };
|
||||
}
|
||||
|
||||
/**
|
||||
* Because AbstractTransactionalSpringContextTests is used, this method will
|
||||
* be called by Spring to set the JobRepository.
|
||||
*/
|
||||
public void setJobInstanceDao(JobInstanceDao jobInstanceDao) {
|
||||
this.jobInstanceDao = jobInstanceDao;
|
||||
}
|
||||
|
||||
public void setJobExecutionDao(JobExecutionDao jobExecutionDao) {
|
||||
this.jobExecutionDao = jobExecutionDao;
|
||||
}
|
||||
|
||||
protected void onSetUpInTransaction() throws Exception {
|
||||
|
||||
job = new JobSupport("Job1");
|
||||
|
||||
// Create job.
|
||||
jobInstance = jobInstanceDao.createJobInstance(job, jobParameters);
|
||||
|
||||
// Create an execution
|
||||
jobExecutionStartTime = new Date(System.currentTimeMillis());
|
||||
jobExecution = new JobExecution(jobInstance);
|
||||
jobExecution.setStartTime(jobExecutionStartTime);
|
||||
jobExecution.setStatus(BatchStatus.STARTED);
|
||||
jobExecutionDao.saveJobExecution(jobExecution);
|
||||
}
|
||||
|
||||
public void testVersionIsNotNullForJob() throws Exception {
|
||||
int version = jdbcTemplate.queryForInt("select version from BATCH_JOB_INSTANCE where JOB_INSTANCE_ID="
|
||||
+ jobInstance.getId());
|
||||
assertEquals(0, version);
|
||||
}
|
||||
|
||||
public void testVersionIsNotNullForJobExecution() throws Exception {
|
||||
int version = jdbcTemplate.queryForInt("select version from BATCH_JOB_EXECUTION where JOB_EXECUTION_ID="
|
||||
+ jobExecution.getId());
|
||||
assertEquals(0, version);
|
||||
}
|
||||
|
||||
public void testFindNonExistentJob() {
|
||||
// No job should be found since it hasn't been created.
|
||||
JobInstance jobInstance = jobInstanceDao.getJobInstance(new JobSupport("nonexistentJob"), jobParameters);
|
||||
assertNull(jobInstance);
|
||||
}
|
||||
|
||||
public void testFindJob() {
|
||||
|
||||
JobInstance instance = jobInstanceDao.getJobInstance(job, jobParameters);
|
||||
assertNotNull(instance);
|
||||
assertTrue(jobInstance.equals(instance));
|
||||
assertEquals(jobParameters, instance.getJobParameters());
|
||||
}
|
||||
|
||||
public void testFindJobWithNullRuntime() {
|
||||
|
||||
try {
|
||||
jobInstanceDao.getJobInstance(null, null);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that ensures that if you create a job with a given name, then find a
|
||||
* job with the same name, but other pieces of the identifier different, you
|
||||
* get no result, not the existing one.
|
||||
*/
|
||||
public void testCreateJobWithExistingName() {
|
||||
|
||||
Job scheduledJob = new JobSupport("ScheduledJob");
|
||||
jobInstanceDao.createJobInstance(scheduledJob, jobParameters);
|
||||
|
||||
// Modifying the key should bring back a completely different
|
||||
// JobInstance
|
||||
JobParameters tempProps = new JobParametersBuilder().addString("job.key", "testKey1").toJobParameters();
|
||||
|
||||
JobInstance instance;
|
||||
instance = jobInstanceDao.getJobInstance(scheduledJob, jobParameters);
|
||||
assertNotNull(instance);
|
||||
assertEquals(jobParameters, instance.getJobParameters());
|
||||
|
||||
instance = jobInstanceDao.getJobInstance(scheduledJob, tempProps);
|
||||
assertNull(instance);
|
||||
|
||||
}
|
||||
|
||||
public void testUpdateJobExecution() {
|
||||
|
||||
jobExecution.setStatus(BatchStatus.COMPLETED);
|
||||
jobExecution.setExitStatus(ExitStatus.FINISHED);
|
||||
jobExecution.setEndTime(new Date(System.currentTimeMillis()));
|
||||
jobExecutionDao.updateJobExecution(jobExecution);
|
||||
|
||||
List executions = jobExecutionDao.findJobExecutions(jobInstance);
|
||||
assertEquals(executions.size(), 1);
|
||||
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
|
||||
|
||||
}
|
||||
|
||||
public void testSaveJobExecution() {
|
||||
|
||||
List executions = jobExecutionDao.findJobExecutions(jobInstance);
|
||||
assertEquals(executions.size(), 1);
|
||||
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
|
||||
}
|
||||
|
||||
public void testUpdateInvalidJobExecution() {
|
||||
|
||||
// id is invalid
|
||||
JobExecution execution = new JobExecution(jobInstance, new Long(29432));
|
||||
try {
|
||||
jobExecutionDao.updateJobExecution(execution);
|
||||
fail("Expected NoSuchBatchDomainObjectException");
|
||||
}
|
||||
catch (NoSuchObjectException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateNullIdJobExection() {
|
||||
|
||||
JobExecution execution = new JobExecution(jobInstance);
|
||||
try {
|
||||
jobExecutionDao.updateJobExecution(execution);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testIncrementExecutionCount() {
|
||||
|
||||
// 1 JobExection already added in setup
|
||||
assertEquals(jobExecutionDao.getJobExecutionCount(jobInstance), 1);
|
||||
|
||||
// Save new JobExecution for same job
|
||||
JobExecution testJobExecution = new JobExecution(jobInstance);
|
||||
jobExecutionDao.saveJobExecution(testJobExecution);
|
||||
// JobExecutionCount should be incremented by 1
|
||||
assertEquals(jobExecutionDao.getJobExecutionCount(jobInstance), 2);
|
||||
}
|
||||
|
||||
public void testZeroExecutionCount() {
|
||||
|
||||
JobInstance testJob = jobInstanceDao.createJobInstance(new JobSupport("test"), new JobParameters());
|
||||
// no jobExecutions saved for new job, count should be 0
|
||||
assertEquals(jobExecutionDao.getJobExecutionCount(testJob), 0);
|
||||
}
|
||||
|
||||
public void testJobWithSimpleJobIdentifier() throws Exception {
|
||||
|
||||
Job testJob = new JobSupport("test");
|
||||
// Create job.
|
||||
jobInstance = jobInstanceDao.createJobInstance(testJob, jobParameters);
|
||||
|
||||
List jobs = jdbcTemplate.queryForList("SELECT * FROM BATCH_JOB_INSTANCE where JOB_INSTANCE_ID=?",
|
||||
new Object[] { jobInstance.getId() });
|
||||
assertEquals(1, jobs.size());
|
||||
assertEquals("test", ((Map) jobs.get(0)).get("JOB_NAME"));
|
||||
|
||||
}
|
||||
|
||||
public void testJobWithDefaultJobIdentifier() throws Exception {
|
||||
|
||||
Job testDefaultJob = new JobSupport("testDefault");
|
||||
// Create job.
|
||||
jobInstance = jobInstanceDao.createJobInstance(testDefaultJob, jobParameters);
|
||||
|
||||
JobInstance instance = jobInstanceDao.getJobInstance(testDefaultJob, jobParameters);
|
||||
|
||||
assertNotNull(instance);
|
||||
assertEquals(jobParameters.getString("job.key"), instance.getJobParameters().getString(
|
||||
"job.key"));
|
||||
|
||||
}
|
||||
|
||||
public void testFindJobExecutions() {
|
||||
|
||||
List results = jobExecutionDao.findJobExecutions(jobInstance);
|
||||
assertEquals(results.size(), 1);
|
||||
validateJobExecution(jobExecution, (JobExecution) results.get(0));
|
||||
}
|
||||
|
||||
public void testFindJobsWithProperties() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private void validateJobExecution(JobExecution lhs, JobExecution rhs) {
|
||||
|
||||
// equals operator only checks id
|
||||
assertEquals(lhs, rhs);
|
||||
assertEquals(lhs.getStartTime(), rhs.getStartTime());
|
||||
assertEquals(lhs.getEndTime(), rhs.getEndTime());
|
||||
assertEquals(lhs.getStatus(), rhs.getStatus());
|
||||
assertEquals(lhs.getExitStatus(), rhs.getExitStatus());
|
||||
}
|
||||
|
||||
public void testGetLastJobExecution() {
|
||||
JobExecution lastExecution = new JobExecution(jobInstance);
|
||||
lastExecution.setStatus(BatchStatus.STARTED);
|
||||
|
||||
int JUMP_INTO_FUTURE = 1000; // makes sure start time is 'greatest'
|
||||
lastExecution.setStartTime(new Date(System.currentTimeMillis() + JUMP_INTO_FUTURE));
|
||||
jobExecutionDao.saveJobExecution(lastExecution);
|
||||
|
||||
assertEquals(lastExecution, jobExecutionDao.getLastJobExecution(jobInstance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Trying to create instance twice for the same job+parameters causes error
|
||||
*/
|
||||
public void testCreateDuplicateInstance() {
|
||||
|
||||
jobParameters = new JobParameters();
|
||||
|
||||
jobInstanceDao.createJobInstance(job, jobParameters);
|
||||
|
||||
try {
|
||||
jobInstanceDao.createJobInstance(job, jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository.dao;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Tests for step persistence (StepInstanceDao and StepExecutionDao). Because it is very reasonable to assume that there is a
|
||||
* foreign key constraint on the JobId of a step, the JobDao is used to create
|
||||
* jobs, to have an id for creating steps.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSourceSpringContextTests {
|
||||
|
||||
protected JobInstanceDao jobInstanceDao;
|
||||
|
||||
protected StepExecutionDao stepExecutionDao;
|
||||
|
||||
protected JobExecutionDao jobExecutionDao;
|
||||
|
||||
protected JobInstance jobInstance;
|
||||
|
||||
protected Step step1;
|
||||
|
||||
protected Step step2;
|
||||
|
||||
protected StepExecution stepExecution;
|
||||
|
||||
protected JobExecution jobExecution;
|
||||
|
||||
protected JobParameters jobParameters = new JobParameters();
|
||||
|
||||
protected ExecutionContext executionContext;
|
||||
|
||||
public void setJobInstanceDao(JobInstanceDao jobInstanceDao) {
|
||||
this.jobInstanceDao = jobInstanceDao;
|
||||
}
|
||||
|
||||
public void setStepExecutionDao(StepExecutionDao stepExecutionDao) {
|
||||
this.stepExecutionDao = stepExecutionDao;
|
||||
}
|
||||
|
||||
public void setJobExecutionDao(JobExecutionDao jobExecutionDao) {
|
||||
this.jobExecutionDao = jobExecutionDao;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.test.AbstractSingleSpringContextTests#getConfigLocations()
|
||||
*/
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { ClassUtils.addResourcePathToPackagePath(getClass(), "sql-dao-test.xml") };
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.test.AbstractTransactionalSpringContextTests#onSetUpInTransaction()
|
||||
*/
|
||||
protected void onSetUpInTransaction() throws Exception {
|
||||
Job job = new JobSupport("TestJob");
|
||||
jobInstance = jobInstanceDao.createJobInstance(job, jobParameters);
|
||||
step1 = new StepSupport("TestStep1");
|
||||
step2 = new StepSupport("TestStep2");
|
||||
jobExecution = new JobExecution(jobInstance);
|
||||
jobExecutionDao.saveJobExecution(jobExecution);
|
||||
|
||||
stepExecution = new StepExecution(step1, jobExecution, new Long(1));
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
stepExecution.setStartTime(new Date(System.currentTimeMillis()));
|
||||
stepExecutionDao.saveStepExecution(stepExecution);
|
||||
|
||||
executionContext = new ExecutionContext();
|
||||
executionContext.putString("1", "testString1");
|
||||
executionContext.putString("2", "testString2");
|
||||
executionContext.putLong("3", 3);
|
||||
executionContext.putDouble("4", 4.4);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testVersionIsNotNullForStepExecution() throws Exception {
|
||||
int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_EXECUTION where STEP_EXECUTION_ID="
|
||||
+ stepExecution.getId());
|
||||
assertEquals(0, version);
|
||||
}
|
||||
|
||||
public void testUpdateStepWithExecutionContext() {
|
||||
stepExecution.setExecutionContext(executionContext);
|
||||
stepExecutionDao.saveOrUpdateExecutionContext(stepExecution);
|
||||
ExecutionContext tempAttributes = stepExecutionDao.findExecutionContext(stepExecution);
|
||||
assertEquals(executionContext, tempAttributes);
|
||||
}
|
||||
|
||||
public void testSaveStepExecution() {
|
||||
StepExecution execution = new StepExecution(step2, jobExecution, null);
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
execution.setStartTime(new Date(System.currentTimeMillis()));
|
||||
execution.setExitStatus(new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION,
|
||||
"java.lang.Exception"));
|
||||
stepExecutionDao.saveStepExecution(execution);
|
||||
StepExecution retrievedExecution = stepExecutionDao.getStepExecution(jobExecution, step2);
|
||||
assertNotNull(retrievedExecution);
|
||||
assertEquals(execution, retrievedExecution);
|
||||
assertEquals(execution.getExitStatus(), retrievedExecution.getExitStatus());
|
||||
}
|
||||
|
||||
public void testSaveStepExecutionAndExecutionContext() {
|
||||
StepExecution execution = new StepExecution(step2, jobExecution, null);
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
execution.setStartTime(new Date(System.currentTimeMillis()));
|
||||
execution.setExecutionContext(executionContext);
|
||||
execution.setExitStatus(new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION,
|
||||
"java.lang.Exception"));
|
||||
stepExecutionDao.saveStepExecution(execution);
|
||||
stepExecutionDao.saveOrUpdateExecutionContext(execution);
|
||||
StepExecution retrievedExecution = stepExecutionDao.getStepExecution(jobExecution, step2);
|
||||
assertNotNull(retrievedExecution);
|
||||
assertEquals(execution, retrievedExecution);
|
||||
assertEquals(execution.getExecutionContext().getString("1"), retrievedExecution.getExecutionContext().getString("1"));
|
||||
assertEquals(execution.getExecutionContext().getLong("3"), retrievedExecution.getExecutionContext().getLong("3"));
|
||||
assertEquals(execution.getExitStatus(), retrievedExecution.getExitStatus());
|
||||
}
|
||||
|
||||
public void testUpdateStepExecution() {
|
||||
|
||||
stepExecution.setStatus(BatchStatus.COMPLETED);
|
||||
stepExecution.setEndTime(new Date(System.currentTimeMillis()));
|
||||
stepExecution.setCommitCount(5);
|
||||
stepExecution.setTaskCount(5);
|
||||
stepExecution.setExecutionContext(new ExecutionContext());
|
||||
stepExecution.setExitStatus(new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION,
|
||||
"java.lang.Exception"));
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
StepExecution retrievedExecution = stepExecutionDao.getStepExecution(jobExecution, step1);
|
||||
assertNotNull(retrievedExecution);
|
||||
assertEquals(stepExecution, retrievedExecution);
|
||||
assertEquals(stepExecution.getExitStatus(), retrievedExecution.getExitStatus());
|
||||
}
|
||||
|
||||
public void testUpdateStepExecutionWithNullId() {
|
||||
StepExecution stepExecution = new StepExecution(new StepSupport("testStep"), null, null);
|
||||
try {
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateStepExecutionVersion() throws Exception {
|
||||
int before = stepExecution.getVersion().intValue();
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
int after = stepExecution.getVersion().intValue();
|
||||
assertEquals("StepExecution version not updated", before + 1, after);
|
||||
}
|
||||
|
||||
public void testUpdateStepExecutionOptimisticLocking() throws Exception {
|
||||
stepExecution.incrementVersion(); // not really allowed outside dao
|
||||
// code
|
||||
try {
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
fail("Expected OptimisticLockingFailureException");
|
||||
}
|
||||
catch (OptimisticLockingFailureException e) {
|
||||
// expected
|
||||
assertTrue("Exception message should contain step execution id: " + e.getMessage(), e.getMessage().indexOf(
|
||||
"" + stepExecution.getId()) >= 0);
|
||||
assertTrue("Exception message should contain step execution version: " + e.getMessage(), e.getMessage()
|
||||
.indexOf("" + stepExecution.getVersion()) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSaveExecutionContext(){
|
||||
|
||||
stepExecution.setExecutionContext(executionContext);
|
||||
stepExecutionDao.saveOrUpdateExecutionContext(stepExecution);
|
||||
ExecutionContext attributes = stepExecutionDao.findExecutionContext(stepExecution);
|
||||
assertEquals(executionContext, attributes);
|
||||
executionContext.putString("newString", "newString");
|
||||
executionContext.putLong("newLong", 1);
|
||||
executionContext.putDouble("newDouble", 2.5);
|
||||
executionContext.put("newSerializable", "serializableValue");
|
||||
stepExecutionDao.saveOrUpdateExecutionContext(stepExecution);
|
||||
attributes = stepExecutionDao.findExecutionContext(stepExecution);
|
||||
assertEquals(executionContext, attributes);
|
||||
}
|
||||
|
||||
public void testGetStepExecution() {
|
||||
assertEquals(stepExecution, stepExecutionDao.getStepExecution(jobExecution, step1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JdbcJobDaoQueryTests extends TestCase {
|
||||
|
||||
JdbcJobExecutionDao jobExecutionDao;
|
||||
|
||||
List list = new ArrayList();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
jobExecutionDao = new JdbcJobExecutionDao();
|
||||
jobExecutionDao.setJobExecutionIncrementer(new DataFieldMaxValueIncrementer() {
|
||||
|
||||
public int nextIntValue() throws DataAccessException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long nextLongValue() throws DataAccessException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String nextStringValue() throws DataAccessException {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void testTablePrefix() throws Exception {
|
||||
jobExecutionDao.setTablePrefix("FOO_");
|
||||
jobExecutionDao.setJdbcTemplate(new JdbcTemplate() {
|
||||
public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
|
||||
list.add(sql);
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
JobExecution jobExecution = new JobExecution(new JobInstance(new Long(11), new JobParameters(), new JobSupport(
|
||||
"testJob")));
|
||||
|
||||
jobExecutionDao.saveJobExecution(jobExecution);
|
||||
assertEquals(1, list.size());
|
||||
String query = (String) list.get(0);
|
||||
assertTrue("Query did not contain FOO_:" + query, query.indexOf("FOO_") >= 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
public class JdbcJobDaoTests extends AbstractJobDaoTests {
|
||||
|
||||
public static final String LONG_STRING = "A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String ";
|
||||
|
||||
protected void onSetUpBeforeTransaction() throws Exception {
|
||||
((JdbcJobInstanceDao) jobInstanceDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX);
|
||||
((JdbcJobExecutionDao) jobExecutionDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX);
|
||||
}
|
||||
|
||||
public void testUpdateJobExecutionWithLongExitCode() {
|
||||
|
||||
assertTrue(LONG_STRING.length() > 250);
|
||||
jobExecution.setExitStatus(ExitStatus.FINISHED
|
||||
.addExitDescription(LONG_STRING));
|
||||
jobExecutionDao.updateJobExecution(jobExecution);
|
||||
|
||||
List executions = jdbcTemplate.queryForList(
|
||||
"SELECT * FROM BATCH_JOB_EXECUTION where JOB_INSTANCE_ID=?",
|
||||
new Object[] { jobInstance.getId() });
|
||||
assertEquals(1, executions.size());
|
||||
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0))
|
||||
.get("EXIT_MESSAGE"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
|
||||
|
||||
/**
|
||||
* Unit Test of SqlStepDao that only tests prefix matching. A
|
||||
* separate test is needed because all other tests hit hsql,
|
||||
* while this test needs to mock JdbcTemplate to analyze the
|
||||
* Sql passed in.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JdbcStepDaoPrefixTests extends TestCase {
|
||||
|
||||
private JdbcStepExecutionDao stepExecutionDao;
|
||||
|
||||
MockJdbcTemplate jdbcTemplate = new MockJdbcTemplate();
|
||||
|
||||
JobInstance job = new JobInstance(new Long(1), new JobParameters(), new JobSupport("testJob"));
|
||||
Step step = new StepSupport("foo");
|
||||
StepExecution stepExecution = new StepExecution(step, new JobExecution(job), null);
|
||||
|
||||
MockControl stepExecutionIncrementerControl = MockControl.createControl(DataFieldMaxValueIncrementer.class);
|
||||
DataFieldMaxValueIncrementer stepExecutionIncrementer;
|
||||
MockControl stepIncrementerControl = MockControl.createControl(DataFieldMaxValueIncrementer.class);
|
||||
DataFieldMaxValueIncrementer stepIncrementer;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
stepExecutionDao = new JdbcStepExecutionDao();
|
||||
stepExecutionIncrementer = (DataFieldMaxValueIncrementer)stepExecutionIncrementerControl.getMock();
|
||||
stepIncrementer = (DataFieldMaxValueIncrementer)stepIncrementerControl.getMock();
|
||||
|
||||
stepExecutionDao.setJdbcTemplate(jdbcTemplate);
|
||||
stepExecutionDao.setStepExecutionIncrementer(stepExecutionIncrementer);
|
||||
stepExecution.setId(new Long(1));
|
||||
stepExecution.incrementVersion();
|
||||
|
||||
}
|
||||
|
||||
public void testModifiedUpdateStepExecution(){
|
||||
stepExecutionDao.setTablePrefix("FOO_");
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1);
|
||||
}
|
||||
|
||||
public void testModifiedSaveStepExecution(){
|
||||
stepExecutionDao.setTablePrefix("FOO_");
|
||||
stepExecutionIncrementer.nextLongValue();
|
||||
stepExecutionIncrementerControl.setReturnValue(1);
|
||||
stepExecutionIncrementerControl.replay();
|
||||
stepExecutionDao.saveStepExecution(stepExecution);
|
||||
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1);
|
||||
}
|
||||
|
||||
public void testDefaultSaveStepExecution(){
|
||||
stepExecutionIncrementer.nextLongValue();
|
||||
stepExecutionIncrementerControl.setReturnValue(1);
|
||||
stepExecutionIncrementerControl.replay();
|
||||
stepExecutionDao.saveStepExecution(stepExecution);
|
||||
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1);
|
||||
}
|
||||
|
||||
public void testDefaultUpdateStepExecution(){
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1);
|
||||
}
|
||||
|
||||
private class MockJdbcTemplate extends JdbcTemplate {
|
||||
|
||||
private String sql;
|
||||
|
||||
public int update(String sql, Object[] args) throws DataAccessException {
|
||||
this.sql = sql;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
|
||||
this.sql = sql;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public List query(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException {
|
||||
this.sql = sql;
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSqlStatement() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
public class JdbcStepDaoTests extends AbstractStepDaoTests {
|
||||
|
||||
private static final String LONG_STRING = JdbcJobDaoTests.LONG_STRING;
|
||||
|
||||
protected void onSetUpBeforeTransaction() throws Exception {
|
||||
((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX);
|
||||
}
|
||||
|
||||
public void testTablePrefix() throws Exception {
|
||||
// ((JdbcStepInstanceDao) stepInstanceDao).setTablePrefix("FOO_");
|
||||
// ((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix("FOO_");
|
||||
// try {
|
||||
// testCreateStep();
|
||||
// fail("Expected DataAccessException");
|
||||
// } catch (DataAccessException e) {
|
||||
// // expected
|
||||
// }
|
||||
}
|
||||
|
||||
public void testUpdateStepExecutionWithLongExitCode() {
|
||||
|
||||
assertTrue(LONG_STRING.length()>250);
|
||||
stepExecution.setExitStatus(ExitStatus.FINISHED.addExitDescription(LONG_STRING));
|
||||
stepExecutionDao.updateStepExecution(stepExecution);
|
||||
|
||||
List executions = jdbcTemplate.queryForList(
|
||||
"SELECT * FROM BATCH_STEP_EXECUTION where STEP_NAME=?",
|
||||
new Object[] { step1.getName() });
|
||||
assertEquals(1, executions.size());
|
||||
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0))
|
||||
.get("EXIT_MESSAGE"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
|
||||
public class MapJobExecutionDaoTests extends TestCase {
|
||||
|
||||
JobExecutionDao dao = new MapJobExecutionDao();
|
||||
|
||||
JobInstance jobInstance = new JobInstance(new Long(1), new JobParameters(), new JobSupport("execTestJob"));
|
||||
|
||||
JobExecution execution = new JobExecution(jobInstance);
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
MapJobExecutionDao.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save and find a job execution.
|
||||
*/
|
||||
public void testSaveAndFind() {
|
||||
|
||||
dao.saveJobExecution(execution);
|
||||
|
||||
List executions = dao.findJobExecutions(jobInstance);
|
||||
assertTrue(executions.size() == 1);
|
||||
assertEquals(execution, executions.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving sets id to the entity.
|
||||
*/
|
||||
public void testSaveAddsId() {
|
||||
|
||||
assertNull(execution.getId());
|
||||
dao.saveJobExecution(execution);
|
||||
assertNotNull(execution.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution count increases by one with every save for the same job
|
||||
* instance.
|
||||
*/
|
||||
public void testGetExecutionCount() {
|
||||
|
||||
JobExecution exec1 = new JobExecution(jobInstance);
|
||||
JobExecution exec2 = new JobExecution(jobInstance);
|
||||
|
||||
dao.saveJobExecution(exec1);
|
||||
assertEquals(1, dao.getJobExecutionCount(jobInstance));
|
||||
|
||||
dao.saveJobExecution(exec2);
|
||||
assertEquals(2, dao.getJobExecutionCount(jobInstance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update and retrieve job execution - check attributes have changed as
|
||||
* expected.
|
||||
*/
|
||||
public void testUpdateExecution() {
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
dao.saveJobExecution(execution);
|
||||
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
dao.updateJobExecution(execution);
|
||||
|
||||
JobExecution updated = (JobExecution) dao.findJobExecutions(jobInstance).get(0);
|
||||
assertEquals(execution, updated);
|
||||
assertEquals(BatchStatus.COMPLETED, updated.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the execution with most recent start time is returned
|
||||
*/
|
||||
public void testGetLastExecution() {
|
||||
JobExecution exec1 = new JobExecution(jobInstance);
|
||||
exec1.setStartTime(new Date(0));
|
||||
JobExecution exec2 = new JobExecution(jobInstance);
|
||||
exec2.setStartTime(new Date(1));
|
||||
|
||||
dao.saveJobExecution(exec1);
|
||||
dao.saveJobExecution(exec2);
|
||||
|
||||
assertEquals(exec2, dao.getLastJobExecution(jobInstance));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
|
||||
public class MapJobInstanceDaoTests extends TestCase {
|
||||
|
||||
private JobInstanceDao dao = new MapJobInstanceDao();
|
||||
|
||||
private Job fooJob = new JobSupport("foo");
|
||||
|
||||
private JobParameters fooParams = new JobParametersBuilder().addString("fooKey", "fooValue").toJobParameters();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
MapJobInstanceDao.clear();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
MapJobInstanceDao.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and retrieve a job instance.
|
||||
*/
|
||||
public void testCreateAndRetrieve() throws Exception {
|
||||
|
||||
JobInstance fooInstance = dao.createJobInstance(fooJob, fooParams);
|
||||
assertNotNull(fooInstance.getId());
|
||||
assertEquals(fooJob, fooInstance.getJob());
|
||||
assertEquals(fooParams, fooInstance.getJobParameters());
|
||||
|
||||
JobInstance retrievedInstance = dao.getJobInstance(fooJob, fooParams);
|
||||
assertEquals(fooInstance, retrievedInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trying to create instance twice for the same job+parameters causes error
|
||||
*/
|
||||
public void testCreateDuplicateInstance() {
|
||||
|
||||
dao.createJobInstance(fooJob, fooParams);
|
||||
|
||||
try {
|
||||
dao.createJobInstance(fooJob, fooParams);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
|
||||
public class MapStepExecutionDaoTests extends TestCase {
|
||||
|
||||
private StepExecutionDao dao = new MapStepExecutionDao();
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private JobExecution jobExecution;
|
||||
|
||||
private Step step;
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
MapStepExecutionDao.clear();
|
||||
jobInstance = new JobInstance(new Long(1), new JobParameters(), new JobSupport("testJob"));
|
||||
jobExecution = new JobExecution(jobInstance, new Long(1));
|
||||
step = new StepSupport("foo");
|
||||
stepExecution = new StepExecution(step, jobExecution);
|
||||
}
|
||||
|
||||
public void testSaveExecutionUpdatesId() throws Exception {
|
||||
StepExecution execution = new StepExecution(step, new JobExecution(jobInstance, new Long(1)));
|
||||
assertNull(execution.getId());
|
||||
dao.saveStepExecution(execution);
|
||||
assertNotNull(execution.getId());
|
||||
}
|
||||
|
||||
public void testSaveAndFindExecution() {
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
dao.saveStepExecution(stepExecution);
|
||||
|
||||
StepExecution retrieved = dao.getStepExecution(jobExecution, step);
|
||||
assertEquals(stepExecution, retrieved);
|
||||
assertEquals(BatchStatus.STARTED, retrieved.getStatus());
|
||||
}
|
||||
|
||||
public void testUpdateExecution() {
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
dao.saveStepExecution(stepExecution);
|
||||
|
||||
stepExecution.setStatus(BatchStatus.STOPPED);
|
||||
dao.updateStepExecution(stepExecution);
|
||||
|
||||
StepExecution retrieved = dao.getStepExecution(jobExecution, step);
|
||||
assertEquals(stepExecution, retrieved);
|
||||
assertEquals(BatchStatus.STOPPED, retrieved.getStatus());
|
||||
}
|
||||
|
||||
public void testSaveAndFindContext() {
|
||||
ExecutionContext ctx = new ExecutionContext(new HashMap() {
|
||||
{
|
||||
put("key", "value");
|
||||
}
|
||||
});
|
||||
stepExecution.setExecutionContext(ctx);
|
||||
dao.saveOrUpdateExecutionContext(stepExecution);
|
||||
|
||||
ExecutionContext retrieved = dao.findExecutionContext(stepExecution);
|
||||
assertEquals(ctx, retrieved);
|
||||
}
|
||||
|
||||
public void testUpdateContext() {
|
||||
ExecutionContext ctx = new ExecutionContext(new HashMap() {
|
||||
{
|
||||
put("key", "value");
|
||||
}
|
||||
});
|
||||
stepExecution.setExecutionContext(ctx);
|
||||
dao.saveOrUpdateExecutionContext(stepExecution);
|
||||
|
||||
ctx.putLong("longKey", 7);
|
||||
dao.saveOrUpdateExecutionContext(stepExecution);
|
||||
|
||||
ExecutionContext retrieved = dao.findExecutionContext(stepExecution);
|
||||
assertEquals(ctx, retrieved);
|
||||
assertEquals(7, retrieved.getLong("longKey"));
|
||||
}
|
||||
|
||||
public void testConcurrentModificationException() {
|
||||
jobInstance = new JobInstance(new Long(1), new JobParameters(), new JobSupport("testJob"));
|
||||
jobExecution = new JobExecution(jobInstance, new Long(1));
|
||||
step = new StepSupport("foo");
|
||||
|
||||
StepExecution exec1 = new StepExecution(step, jobExecution);
|
||||
dao.saveStepExecution(exec1);
|
||||
|
||||
StepExecution exec2 = new StepExecution(step, jobExecution);
|
||||
exec2.setId(exec1.getId());
|
||||
|
||||
exec2.incrementVersion();
|
||||
assertEquals(new Integer(0), exec1.getVersion());
|
||||
assertEquals(exec1.getVersion(), exec2.getVersion());
|
||||
|
||||
dao.updateStepExecution(exec1);
|
||||
assertEquals(new Integer(1), exec1.getVersion());
|
||||
|
||||
try {
|
||||
dao.updateStepExecution(exec2);
|
||||
fail();
|
||||
}
|
||||
catch (OptimisticLockingFailureException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.repository.dao;
|
||||
|
||||
import org.springframework.batch.execution.repository.dao.NoSuchObjectException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class NoSuchBatchDomainObjectExceptionTests extends TestCase {
|
||||
|
||||
public void testCreateException() throws Exception {
|
||||
NoSuchObjectException e = new NoSuchObjectException("Foo");
|
||||
assertEquals("Foo", e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.StepSupport;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link StepExecutionProxyResource}
|
||||
*
|
||||
* @author robert.kasanicky
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class StepExecutionProxyResourceTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Object under test
|
||||
*/
|
||||
private StepExecutionProxyResource resource = new StepExecutionProxyResource();
|
||||
|
||||
private char pathsep = File.separatorChar;
|
||||
|
||||
private String path = "data" + pathsep;
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
/**
|
||||
* mock step context
|
||||
*/
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
jobInstance = new JobInstance(new Long(0), new JobParameters(), new JobSupport("testJob"));
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
Step step = new StepSupport("bar");
|
||||
stepExecution = jobExecution.createStepExecution(step);
|
||||
resource.beforeStep(stepExecution);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* regular use with valid context and pattern provided
|
||||
*/
|
||||
public void testCreateFileName() throws Exception {
|
||||
doTestPathName("bar.txt", path);
|
||||
}
|
||||
|
||||
public void testNullFilePattern() throws Exception {
|
||||
resource.setFilePattern(null);
|
||||
try {
|
||||
resource.beforeStep(stepExecution);
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testNonStandardFilePattern() throws Exception {
|
||||
resource.setFilePattern("foo/data/%JOB_NAME%/" + "%STEP_NAME%-job");
|
||||
resource.beforeStep(stepExecution);
|
||||
doTestPathName("bar-job", "foo" + pathsep + "data" + pathsep);
|
||||
}
|
||||
|
||||
public void testNonStandardFilePatternWithJobParameters() throws Exception {
|
||||
resource.setFilePattern("foo/data/%JOB_NAME%/%job.key%-foo");
|
||||
jobInstance = new JobInstance(new Long(0), new JobParametersBuilder().addString("job.key", "spam")
|
||||
.toJobParameters(), new JobSupport("testJob"));
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
Step step = new StepSupport("bar");
|
||||
resource.beforeStep(jobExecution.createStepExecution(step));
|
||||
doTestPathName("spam-foo", "foo" + pathsep + "data" + pathsep);
|
||||
}
|
||||
|
||||
public void testResoureLoaderAware() throws Exception {
|
||||
resource = new StepExecutionProxyResource();
|
||||
resource.setResourceLoader(new DefaultResourceLoader() {
|
||||
public Resource getResource(String location) {
|
||||
return new ByteArrayResource("foo".getBytes());
|
||||
}
|
||||
});
|
||||
resource.beforeStep(stepExecution);
|
||||
assertTrue(resource.exists());
|
||||
}
|
||||
|
||||
private void doTestPathName(String filename, String path) throws Exception, IOException {
|
||||
String returnedPath = resource.getFile().getAbsolutePath();
|
||||
String absolutePath = new File(path + jobInstance.getJobName() + pathsep + filename).getAbsolutePath();
|
||||
assertEquals(absolutePath, returnedPath);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepContribution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepListener;
|
||||
import org.springframework.batch.core.listener.StepListenerSupport;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.execution.step.support.JobRepositorySupport;
|
||||
import org.springframework.batch.execution.step.support.SimpleItemHandler;
|
||||
import org.springframework.batch.execution.step.support.StepInterruptionPolicy;
|
||||
import org.springframework.batch.item.AbstractItemReader;
|
||||
import org.springframework.batch.item.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemStreamSupport;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.MarkFailedException;
|
||||
import org.springframework.batch.item.ResetFailedException;
|
||||
import org.springframework.batch.item.ItemStreamException;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
|
||||
public class ItemOrientedStepTests extends TestCase {
|
||||
|
||||
ArrayList processed = new ArrayList();
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
ItemWriter itemWriter = new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
processed.add((String) data);
|
||||
}
|
||||
};
|
||||
|
||||
private ItemOrientedStep itemOrientedStep;
|
||||
|
||||
private RepeatTemplate template;
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private ResourcelessTransactionManager transactionManager;
|
||||
|
||||
private ItemReader getReader(String[] args) {
|
||||
return new ListItemReader(Arrays.asList(args));
|
||||
}
|
||||
|
||||
private AbstractStep getStep(String[] strings) throws Exception {
|
||||
ItemOrientedStep step = new ItemOrientedStep("stepName");
|
||||
step.setItemHandler(new SimpleItemHandler(getReader(strings), itemWriter));
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
step.setTransactionManager(transactionManager);
|
||||
return step;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
MapJobInstanceDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
|
||||
transactionManager = new ResourcelessTransactionManager();
|
||||
|
||||
itemOrientedStep = (ItemOrientedStep) getStep(new String[] { "foo", "bar", "spam" });
|
||||
template = new RepeatTemplate();
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
itemOrientedStep.setStepOperations(template);
|
||||
// Only process one item:
|
||||
template = new RepeatTemplate();
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
itemOrientedStep.setChunkOperations(template);
|
||||
|
||||
jobInstance = new JobInstance(new Long(0), new JobParameters(), new JobSupport("FOO"));
|
||||
|
||||
itemOrientedStep.setTransactionManager(transactionManager);
|
||||
|
||||
}
|
||||
|
||||
public void testStepExecutor() throws Exception {
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
assertEquals(1, stepExecution.getTaskCount().intValue());
|
||||
}
|
||||
|
||||
public void testChunkExecutor() throws Exception {
|
||||
|
||||
template = new RepeatTemplate();
|
||||
|
||||
// Only process one item:
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
itemOrientedStep.setChunkOperations(template);
|
||||
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
StepContribution contribution = stepExecution.createStepContribution();
|
||||
itemOrientedStep.processChunk(contribution);
|
||||
assertEquals(1, processed.size());
|
||||
assertEquals(0, stepExecution.getTaskCount().intValue());
|
||||
assertEquals(1, contribution.getTaskCount());
|
||||
|
||||
}
|
||||
|
||||
public void testRepository() throws Exception {
|
||||
|
||||
SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
|
||||
new MapStepExecutionDao());
|
||||
itemOrientedStep.setJobRepository(repository);
|
||||
|
||||
JobExecution jobExecution = repository.createJobExecution(jobInstance.getJob(), jobInstance.getJobParameters());
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
}
|
||||
|
||||
public void testIncrementRollbackCount() {
|
||||
|
||||
ItemReader itemReader = new AbstractItemReader() {
|
||||
|
||||
public Object read() throws Exception {
|
||||
int counter = 0;
|
||||
counter++;
|
||||
|
||||
if (counter == 1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
} catch (Exception ex) {
|
||||
assertEquals(stepExecution.getRollbackCount(), new Integer(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testExitCodeDefaultClassification() throws Exception {
|
||||
|
||||
ItemReader itemReader = new AbstractItemReader() {
|
||||
|
||||
public Object read() throws Exception {
|
||||
int counter = 0;
|
||||
counter++;
|
||||
|
||||
if (counter == 1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
} catch (Exception ex) {
|
||||
ExitStatus status = stepExecution.getExitStatus();
|
||||
assertFalse(status.isContinuable());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure a job that has never been executed before, but does have saveExecutionAttributes = true, doesn't have
|
||||
* restoreFrom called on it.
|
||||
*/
|
||||
public void testNonRestartedJob() throws Exception {
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(tasklet, itemWriter));
|
||||
itemOrientedStep.registerStream(tasklet);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
assertFalse(tasklet.isRestoreFromCalled());
|
||||
assertTrue(tasklet.isGetExecutionAttributesCalled());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithExecutionContext() throws Exception {
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
itemOrientedStep.setJobRepository(new JobRepositorySupport() {
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
list.add(stepExecution);
|
||||
}
|
||||
});
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithFailureOnSaveOfExecutionContext() throws Exception {
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
itemOrientedStep.setJobRepository(new JobRepositorySupport() {
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
});
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
} catch (UnexpectedJobExecutionException e) {
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure a job that has been executed before, and is therefore being restarted, is restored.
|
||||
*/
|
||||
// public void testRestartedJob() throws Exception {
|
||||
// String step = "stepName";
|
||||
// // step.setStepExecutionCount(1);
|
||||
// MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
// stepExecutor.setItemReader(tasklet);
|
||||
// stepConfiguration.setSaveExecutionContext(true);
|
||||
// JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
//
|
||||
// stepExecution
|
||||
// .setExecutionContext(new
|
||||
// ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// // step.setLastExecution(stepExecution);
|
||||
// stepExecutor.execute(stepExecution);
|
||||
//
|
||||
// assertTrue(tasklet.isRestoreFromCalled());
|
||||
// assertTrue(tasklet.isRestoreFromCalledWithSomeContext());
|
||||
// assertTrue(tasklet.isGetExecutionAttributesCalled());
|
||||
// }
|
||||
/*
|
||||
* Test that a job that is being restarted, but has saveExecutionAttributes set to false, doesn't have restore or
|
||||
* getExecutionAttributes called on it.
|
||||
*/
|
||||
public void testNoSaveExecutionAttributesRestartableJob() {
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(tasklet, itemWriter));
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
} catch (Throwable t) {
|
||||
fail();
|
||||
}
|
||||
|
||||
assertFalse(tasklet.isRestoreFromCalled());
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though the job is restarted, and saveExecutionAttributes is true, nothing will be restored because the
|
||||
* Tasklet does not implement Restartable.
|
||||
*/
|
||||
public void testRestartJobOnNonRestartableTasklet() throws Exception {
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return "foo";
|
||||
}
|
||||
}, itemWriter));
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
}
|
||||
|
||||
public void testStreamManager() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public void update(ExecutionContext executionContext) {
|
||||
// TODO Auto-generated method stub
|
||||
executionContext.putString("foo", "bar");
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(reader, itemWriter));
|
||||
itemOrientedStep.registerStream(reader);
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
|
||||
assertEquals(false, stepExecution.getExecutionContext().containsKey("foo"));
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
// At least once in that process the statistics service was asked for
|
||||
// statistics...
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
public void testDirectlyInjectedItemStream() throws Exception {
|
||||
itemOrientedStep.setStreams(new ItemStream[] { new ItemStreamSupport() {
|
||||
public void update(ExecutionContext executionContext) {
|
||||
executionContext.putString("foo", "bar");
|
||||
}
|
||||
} });
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
|
||||
assertEquals(false, stepExecution.getExecutionContext().containsKey("foo"));
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
public void testDirectlyInjectedListener() throws Exception {
|
||||
itemOrientedStep.registerStepListener(new StepListenerSupport() {
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
list.add("foo");
|
||||
}
|
||||
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("bar");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
public void testListenerCalledBeforeStreamOpened() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
list.add("foo");
|
||||
}
|
||||
|
||||
public void open(ExecutionContext executionContext) throws ItemStreamException {
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setStreams(new ItemStream[] { reader });
|
||||
itemOrientedStep.registerStepListener(reader);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, new JobExecution(jobInstance));
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testAfterStep() throws Exception {
|
||||
|
||||
final ExitStatus customStatus = new ExitStatus(false, "custom code");
|
||||
|
||||
itemOrientedStep.setStepListeners(new StepListener[] { new StepListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("afterStepCalled");
|
||||
return customStatus;
|
||||
}
|
||||
} });
|
||||
|
||||
RepeatTemplate stepTemplate = new RepeatTemplate();
|
||||
stepTemplate.setCompletionPolicy(new SimpleCompletionPolicy(5));
|
||||
itemOrientedStep.setStepOperations(stepTemplate);
|
||||
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, list.size());
|
||||
ExitStatus returnedStatus = stepExecution.getExitStatus();
|
||||
assertEquals(customStatus.getExitCode(), returnedStatus.getExitCode());
|
||||
assertEquals(customStatus.getExitDescription(), returnedStatus.getExitDescription());
|
||||
}
|
||||
|
||||
public void testDirectlyInjectedListenerOnError() throws Exception {
|
||||
itemOrientedStep.registerStepListener(new StepListenerSupport() {
|
||||
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
|
||||
list.add(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(new MockRestartableItemReader() {
|
||||
public Object read() throws Exception {
|
||||
throw new RuntimeException("FOO");
|
||||
}
|
||||
}, itemWriter));
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected RuntimeException");
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("FOO", e.getMessage());
|
||||
}
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testDirectlyInjectedStreamWhichIsAlsoReader() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public void update(ExecutionContext executionContext) {
|
||||
// TODO Auto-generated method stub
|
||||
executionContext.putString("foo", "bar");
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(reader, itemWriter));
|
||||
itemOrientedStep.setStreams(new ItemStream[] { reader });
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecution);
|
||||
|
||||
assertEquals(false, stepExecution.getExecutionContext().containsKey("foo"));
|
||||
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
// At least once in that process the statistics service was asked for
|
||||
// statistics...
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
public void testStatusForInterruptedException() {
|
||||
|
||||
StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy() {
|
||||
|
||||
public void checkInterrupted(RepeatContext context) throws JobInterruptedException {
|
||||
throw new JobInterruptedException("");
|
||||
}
|
||||
};
|
||||
|
||||
itemOrientedStep.setInterruptionPolicy(interruptionPolicy);
|
||||
|
||||
ItemReader itemReader = new AbstractItemReader() {
|
||||
|
||||
public Object read() throws Exception {
|
||||
int counter = 0;
|
||||
counter++;
|
||||
|
||||
if (counter == 1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected StepInterruptedException");
|
||||
} catch (JobInterruptedException ex) {
|
||||
assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain JobInterruptedException: " + msg, msg
|
||||
.contains("JobInterruptedException"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForNormalFailure() throws Exception {
|
||||
|
||||
ItemReader itemReader = new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
// Trigger a rollback
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected RuntimeException");
|
||||
} catch (RuntimeException ex) {
|
||||
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Foo", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForResetFailedException() throws Exception {
|
||||
|
||||
ItemReader itemReader = new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
// Trigger a rollback
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
itemOrientedStep.setTransactionManager(new ResourcelessTransactionManager() {
|
||||
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
|
||||
// Simulate failure on rollback when stream resets
|
||||
throw new ResetFailedException("Bar");
|
||||
}
|
||||
});
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain ResetFailedException: " + msg, msg.contains("ResetFailedException"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForCommitFailedException() throws Exception {
|
||||
|
||||
itemOrientedStep.setTransactionManager(new ResourcelessTransactionManager() {
|
||||
protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
|
||||
// Simulate failure on rollback when stream resets
|
||||
throw new RuntimeException("Bar");
|
||||
}
|
||||
});
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'saving': " + msg, msg.contains("saving"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForFinalUpdateFailedException() throws Exception {
|
||||
|
||||
itemOrientedStep.setJobRepository(new JobRepositorySupport() {
|
||||
public void saveOrUpdate(StepExecution stepExecution) {
|
||||
if (stepExecution.getEndTime() != null) {
|
||||
throw new RuntimeException("Bar");
|
||||
}
|
||||
super.saveOrUpdate(stepExecution);
|
||||
}
|
||||
});
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected RuntimeException");
|
||||
} catch (RuntimeException ex) {
|
||||
// The job actually completeed, but teh streams couldn't be closed.
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'final': " + msg, msg.contains("final"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForCloseFailedException() throws Exception {
|
||||
|
||||
MockRestartableItemReader itemReader = new MockRestartableItemReader() {
|
||||
public void close(ExecutionContext executionContext) throws ItemStreamException {
|
||||
super.close(executionContext);
|
||||
// Simulate failure on rollback when stream resets
|
||||
throw new RuntimeException("Bar");
|
||||
}
|
||||
};
|
||||
itemOrientedStep.setItemHandler(new SimpleItemHandler(itemReader, itemWriter));
|
||||
itemOrientedStep.registerStream(itemReader);
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(itemOrientedStep, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected InfrastructureException");
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
// The job actually completeed, but the streams couldn't be closed.
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'close': " + msg, msg.contains("close"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class MockRestartableItemReader extends ItemStreamSupport implements ItemReader, StepListener {
|
||||
|
||||
private boolean getExecutionAttributesCalled = false;
|
||||
|
||||
private boolean restoreFromCalled = false;
|
||||
|
||||
private boolean restoreFromCalledWithSomeContext = false;
|
||||
|
||||
public Object read() throws Exception {
|
||||
return "item";
|
||||
}
|
||||
|
||||
public boolean isRestoreFromCalledWithSomeContext() {
|
||||
return restoreFromCalledWithSomeContext;
|
||||
}
|
||||
|
||||
public void update(ExecutionContext executionContext) {
|
||||
getExecutionAttributesCalled = true;
|
||||
executionContext.putString("spam", "bucket");
|
||||
}
|
||||
|
||||
public boolean isGetExecutionAttributesCalled() {
|
||||
return getExecutionAttributesCalled;
|
||||
}
|
||||
|
||||
public boolean isRestoreFromCalled() {
|
||||
return restoreFromCalled;
|
||||
}
|
||||
|
||||
public void mark() throws MarkFailedException {
|
||||
}
|
||||
|
||||
public void reset() throws ResetFailedException {
|
||||
}
|
||||
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step;
|
||||
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
||||
/**
|
||||
* Basic no-op support implementation for use as base class for {@link Step}. Implements {@link BeanNameAware} so that
|
||||
* if no name is provided explicitly it will be inferred from the bean definition in Spring configuration.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class StepSupport implements Step, BeanNameAware {
|
||||
|
||||
private String name;
|
||||
|
||||
private int startLimit = Integer.MAX_VALUE;
|
||||
|
||||
private boolean allowStartIfComplete;
|
||||
|
||||
/**
|
||||
* Default constructor for {@link StepSupport}.
|
||||
*/
|
||||
public StepSupport() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public StepSupport(String string) {
|
||||
super();
|
||||
this.name = string;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name property if it is not already set. Because of the order of the callbacks in a Spring container the
|
||||
* name property will be set first if it is present. Care is needed with bean definition inheritance - if a parent
|
||||
* bean has a name, then its children need an explicit name as well, otherwise they will not be unique.
|
||||
*
|
||||
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setBeanName(String name) {
|
||||
if (this.name == null) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name property. Always overrides the default value if this object is a Spring bean.
|
||||
*
|
||||
* @see #setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getStartLimit() {
|
||||
return this.startLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the startLimit.
|
||||
*
|
||||
* @param startLimit the startLimit to set
|
||||
*/
|
||||
public void setStartLimit(int startLimit) {
|
||||
this.startLimit = startLimit;
|
||||
}
|
||||
|
||||
public boolean isAllowStartIfComplete() {
|
||||
return this.allowStartIfComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the shouldAllowStartIfComplete.
|
||||
*
|
||||
* @param allowStartIfComplete the shouldAllowStartIfComplete to set
|
||||
*/
|
||||
public void setAllowStartIfComplete(boolean allowStartIfComplete) {
|
||||
this.allowStartIfComplete = allowStartIfComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported but provided so that tests can easily create a step.
|
||||
*
|
||||
* @throws UnsupportedOperationException always
|
||||
*
|
||||
* @see org.springframework.batch.core.Step#execute(org.springframework.batch.core.StepExecution)
|
||||
*/
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot process a StepExecution. Use a smarter subclass of StepSupport.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package org.springframework.batch.execution.step;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepListener;
|
||||
import org.springframework.batch.core.listener.StepListenerSupport;
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.step.support.JobRepositorySupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
public class TaskletStepTests extends TestCase {
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
stepExecution = new StepExecution(new StepSupport("stepName"), new JobExecution(new JobInstance(new Long(0L),
|
||||
new JobParameters(), new JobSupport("testJob")), new Long(12)));
|
||||
}
|
||||
|
||||
public void testTaskletMandatory() throws Exception {
|
||||
TaskletStep step = new TaskletStep();
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
try {
|
||||
step.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testRepositoryMandatory() throws Exception {
|
||||
TaskletStep step = new TaskletStep();
|
||||
try {
|
||||
step.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSuccessfulExecution() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, false), new JobRepositorySupport());
|
||||
step.execute(stepExecution);
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithStepContext() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, false, true), new JobRepositorySupport());
|
||||
step.afterPropertiesSet();
|
||||
step.execute(stepExecution);
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithExecutionContext() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, false), new JobRepositorySupport() {
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
list.add(stepExecution);
|
||||
}
|
||||
});
|
||||
step.execute(stepExecution);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithFailureOnSaveOfExecutionContext() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, false, true), new JobRepositorySupport() {
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
});
|
||||
step.afterPropertiesSet();
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
}
|
||||
catch (UnexpectedJobExecutionException e) {
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
}
|
||||
|
||||
public void testFailureExecution() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(true, false), new JobRepositorySupport());
|
||||
step.execute(stepExecution);
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FAILED, stepExecution.getExitStatus());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
|
||||
public void testSuccessfulExecutionWithListener() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, false), new JobRepositorySupport());
|
||||
step.setStepListeners(new StepListener[] { new StepListenerSupport() {
|
||||
public void beforeStep(StepExecution context) {
|
||||
list.add("open");
|
||||
}
|
||||
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
list.add("close");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
} });
|
||||
step.execute(stepExecution);
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
public void testExceptionExecution() throws JobInterruptedException, UnexpectedJobExecutionException {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(false, true), new JobRepositorySupport());
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FAILED, stepExecution.getExitStatus());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
}
|
||||
|
||||
private class StubTasklet extends StepListenerSupport implements Tasklet {
|
||||
|
||||
private final boolean exitFailure;
|
||||
|
||||
private final boolean throwException;
|
||||
|
||||
private final boolean assertStepContext;
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
public StubTasklet(boolean exitFailure, boolean throwException) {
|
||||
this(exitFailure, throwException, false);
|
||||
}
|
||||
|
||||
public StubTasklet(boolean exitFailure, boolean throwException, boolean assertStepContext) {
|
||||
this.exitFailure = exitFailure;
|
||||
this.throwException = throwException;
|
||||
this.assertStepContext = assertStepContext;
|
||||
}
|
||||
|
||||
public ExitStatus execute() throws Exception {
|
||||
if (throwException) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
if (exitFailure) {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
if (assertStepContext) {
|
||||
assertNotNull(this.stepExecution);
|
||||
}
|
||||
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
this.stepExecution = stepExecution;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchListener;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.listener.ItemListenerSupport;
|
||||
import org.springframework.batch.execution.job.SimpleJob;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.execution.step.AbstractStep;
|
||||
import org.springframework.batch.execution.step.ItemOrientedStep;
|
||||
import org.springframework.batch.item.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.exception.ExceptionHandler;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
|
||||
|
||||
public class DefaultStepFactoryBeanTests extends TestCase {
|
||||
|
||||
private List recovered = new ArrayList();
|
||||
|
||||
private SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
|
||||
new MapStepExecutionDao());
|
||||
|
||||
private List processed = new ArrayList();
|
||||
|
||||
private ItemWriter processor = new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
processed.add((String) data);
|
||||
}
|
||||
};
|
||||
|
||||
private ItemReader provider;
|
||||
|
||||
private SimpleJob job = new SimpleJob();;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
job.setJobRepository(repository);
|
||||
MapJobInstanceDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
}
|
||||
|
||||
private DefaultStepFactoryBean getStep(String arg) throws Exception {
|
||||
return getStep(new String[] { arg });
|
||||
}
|
||||
|
||||
private DefaultStepFactoryBean getStep(String arg0, String arg1) throws Exception {
|
||||
return getStep(new String[] { arg0, arg1 });
|
||||
}
|
||||
|
||||
private DefaultStepFactoryBean getStep(String[] args) throws Exception {
|
||||
DefaultStepFactoryBean factory = new DefaultStepFactoryBean();
|
||||
|
||||
List items = TransactionAwareProxyFactory.createTransactionalList();
|
||||
items.addAll(Arrays.asList(args));
|
||||
provider = new ListItemReader(items);
|
||||
|
||||
factory.setItemReader(provider);
|
||||
factory.setItemWriter(processor);
|
||||
factory.setJobRepository(repository);
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
factory.setBeanName("stepName");
|
||||
return factory;
|
||||
}
|
||||
|
||||
public void testSimpleJob() throws Exception {
|
||||
|
||||
job.setSteps(new ArrayList());
|
||||
AbstractStep step = (AbstractStep) getStep("foo", "bar").getObject();
|
||||
step.setName("step1");
|
||||
job.addStep(step);
|
||||
step = (AbstractStep) getStep("spam").getObject();
|
||||
step.setName("step2");
|
||||
job.addStep(step);
|
||||
|
||||
JobExecution jobExecution = repository.createJobExecution(job, new JobParameters());
|
||||
|
||||
job.execute(jobExecution);
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(3, processed.size());
|
||||
assertTrue(processed.contains("foo"));
|
||||
}
|
||||
|
||||
public void testSimpleJobWithItemListeners() throws Exception {
|
||||
|
||||
final List throwables = new ArrayList();
|
||||
|
||||
RepeatTemplate chunkOperations = new RepeatTemplate();
|
||||
// Always handle the exception a check it is the right one...
|
||||
chunkOperations.setExceptionHandler(new ExceptionHandler() {
|
||||
public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
|
||||
throwables.add(throwable);
|
||||
assertEquals("Error!", throwable.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Each message fails once and the chunk (size=1) "rolls back"; then it
|
||||
* is recovered ("skipped") on the second attempt (see retry policy
|
||||
* definition above)...
|
||||
*/
|
||||
DefaultStepFactoryBean factory = getStep(new String[] { "foo", "bar", "spam" });
|
||||
|
||||
factory.setItemWriter(new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
});
|
||||
factory.setListeners(new BatchListener[] { new ItemListenerSupport() {
|
||||
public void onReadError(Exception ex) {
|
||||
recovered.add(ex);
|
||||
}
|
||||
|
||||
public void onWriteError(Exception ex, Object item) {
|
||||
recovered.add(ex);
|
||||
}
|
||||
} });
|
||||
|
||||
ItemOrientedStep step = (ItemOrientedStep) factory.getObject();
|
||||
step.setChunkOperations(chunkOperations);
|
||||
|
||||
job.setSteps(Collections.singletonList(step));
|
||||
|
||||
JobExecution jobExecution = repository.createJobExecution(job, new JobParameters());
|
||||
job.execute(jobExecution);
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(0, processed.size());
|
||||
// provider should be exhausted
|
||||
assertEquals(null, provider.read());
|
||||
assertEquals(3, recovered.size());
|
||||
}
|
||||
|
||||
public void testExceptionTerminates() throws Exception {
|
||||
DefaultStepFactoryBean factory = getStep(new String[] { "foo", "bar", "spam" });
|
||||
factory.setBeanName("exceptionStep");
|
||||
factory.setItemWriter(new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
});
|
||||
ItemOrientedStep step = (ItemOrientedStep) factory.getObject();
|
||||
job.setSteps(Collections.singletonList(step));
|
||||
|
||||
JobExecution jobExecution = repository.createJobExecution(job, new JobParameters());
|
||||
try {
|
||||
job.execute(jobExecution);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals("Foo", e.getMessage());
|
||||
// expected
|
||||
}
|
||||
assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobRepositorySupport implements JobRepository {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.container.common.repository.JobRepository#findOrCreateJob(org.springframework.batch.container.common.domain.JobConfiguration)
|
||||
*/
|
||||
public JobExecution createJobExecution(Job jobConfiguration, JobParameters jobParameters) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.container.common.repository.JobRepository#saveOrUpdate(org.springframework.batch.container.common.domain.JobExecution)
|
||||
*/
|
||||
public void saveOrUpdate(JobExecution jobExecution) {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.container.common.repository.JobRepository#saveOrUpdate(org.springframework.batch.container.common.domain.StepExecution)
|
||||
*/
|
||||
public void saveOrUpdate(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.repository.JobRepository#saveOrUpdateExecutionContext(org.springframework.batch.core.domain.StepExecution)
|
||||
*/
|
||||
public void saveOrUpdateExecutionContext(StepExecution stepExecution) {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.container.common.repository.JobRepository#update(org.springframework.batch.container.common.domain.Job)
|
||||
*/
|
||||
public void update(JobInstance job) {
|
||||
}
|
||||
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, Step step) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStepExecutionCount(JobInstance jobInstance, Step step) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.MarkFailedException;
|
||||
import org.springframework.batch.item.ResetFailedException;
|
||||
|
||||
public class MockItemReader implements ItemReader {
|
||||
|
||||
private final int returnItemCount;
|
||||
|
||||
private int returnedItemCount;
|
||||
|
||||
private boolean fail = false;
|
||||
|
||||
public MockItemReader() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
public MockItemReader(int returnItemCount) {
|
||||
this.returnItemCount = returnItemCount;
|
||||
}
|
||||
|
||||
public void setFail(boolean fail) {
|
||||
this.fail = fail;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public Object read() {
|
||||
if(fail) {
|
||||
fail = false;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
if (returnItemCount < 0 || returnedItemCount < returnItemCount) {
|
||||
return String.valueOf(returnedItemCount++);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getKey(Object item) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void mark() throws MarkFailedException {
|
||||
}
|
||||
|
||||
public void reset() throws ResetFailedException {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.launch.EmptyItemWriter;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
import org.springframework.batch.repeat.RepeatOperations;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class RepeatOperationsStepFactoryBeanTests extends TestCase {
|
||||
|
||||
private RepeatOperationsStepFactoryBean factory = new RepeatOperationsStepFactoryBean();
|
||||
|
||||
private List list;
|
||||
|
||||
private JobExecution jobExecution = new JobExecution(new JobInstance(new Long(0L), new JobParameters(),
|
||||
new JobSupport("job")));
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
factory.setItemReader(new ListItemReader(new ArrayList()));
|
||||
factory.setItemWriter(new EmptyItemWriter());
|
||||
factory.setJobRepository(new JobRepositorySupport());
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
}
|
||||
|
||||
public void testType() throws Exception {
|
||||
assertEquals(Step.class, factory.getObjectType());
|
||||
}
|
||||
|
||||
public void testDefaultValue() throws Exception {
|
||||
assertTrue(factory.getObject() instanceof Step);
|
||||
}
|
||||
|
||||
public void testStepOperationsWithoutChunkListener() throws Exception {
|
||||
|
||||
factory.setItemReader(new ListItemReader(new ArrayList()));
|
||||
factory.setItemWriter(new EmptyItemWriter());
|
||||
factory.setJobRepository(new JobRepositorySupport());
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
|
||||
factory.setStepOperations(new RepeatOperations() {
|
||||
|
||||
public ExitStatus iterate(RepeatCallback callback) {
|
||||
list = new ArrayList();
|
||||
list.add("foo");
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
});
|
||||
|
||||
Step step = (Step) factory.getObject();
|
||||
step.execute(new StepExecution(step, jobExecution));
|
||||
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.repository.NoSuchJobException;
|
||||
import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier;
|
||||
import org.springframework.batch.execution.launch.support.ExitCodeMapper;
|
||||
import org.springframework.batch.execution.step.support.SimpleExitStatusExceptionClassifier;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class SimpleExitStatusExceptionClassifierTests extends TestCase {
|
||||
|
||||
NullPointerException exception;
|
||||
|
||||
SimpleExitStatusExceptionClassifier classifier = new SimpleExitStatusExceptionClassifier();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
exception = new NullPointerException();
|
||||
}
|
||||
|
||||
public void testClassifyForExitCode() {
|
||||
ExitStatus exitStatus = classifier.classifyForExitCode(exception);
|
||||
assertEquals(exitStatus.getExitCode(), "FATAL_EXCEPTION");
|
||||
String description = exitStatus.getExitDescription();
|
||||
assertTrue("Description does not contain NullPointerException: "+description, description.indexOf("java.lang.NullPointerException")>=0);
|
||||
}
|
||||
|
||||
public void testClassify() {
|
||||
ExitStatus exitStatus = (ExitStatus)classifier.classify(exception);
|
||||
assertEquals(exitStatus.getExitCode(), "FATAL_EXCEPTION");
|
||||
String description = exitStatus.getExitDescription();
|
||||
assertTrue("Description does not contain NullPointerException: "+description, description.indexOf("java.lang.NullPointerException")>=0);
|
||||
}
|
||||
|
||||
public void testGetDefault() {
|
||||
ExitStatus exitStatus = (ExitStatus)classifier.getDefault();
|
||||
assertEquals(exitStatus.getExitCode(), "FATAL_EXCEPTION");
|
||||
assertEquals(exitStatus.getExitDescription(), "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempting to classify a null throwable should lead to a blank description, not a
|
||||
* null pointer exception.
|
||||
*/
|
||||
public void testClassifyNullThrowable(){
|
||||
ExitStatus exitStatus = (ExitStatus)classifier.classify(null);
|
||||
assertEquals(exitStatus.getExitCode(), "FATAL_EXCEPTION");
|
||||
assertEquals(exitStatus.getExitDescription(), "");
|
||||
}
|
||||
|
||||
public void testClassifyInterruptedException(){
|
||||
ExitStatus exitStatus = (ExitStatus)classifier.classifyForExitCode(new JobInterruptedException(""));
|
||||
assertEquals(exitStatus.getExitCode(), ExitStatusExceptionClassifier.JOB_INTERRUPTED);
|
||||
assertEquals(exitStatus.getExitDescription(),
|
||||
JobInterruptedException.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* a NoSuchJobException should lead to the related constant
|
||||
*/
|
||||
public void testClassifyNoSuchJobException() {
|
||||
ExitStatus exitStatus = (ExitStatus)classifier.classifyForExitCode(new NoSuchJobException(""));
|
||||
assertEquals(exitStatus.getExitCode(), ExitCodeMapper.NO_SUCH_JOB);
|
||||
assertEquals(exitStatus.getExitDescription(), "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.context.RepeatContextSupport;
|
||||
import org.springframework.batch.repeat.exception.SimpleLimitExceptionHandler;
|
||||
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
import org.springframework.batch.retry.policy.AlwaysRetryPolicy;
|
||||
import org.springframework.batch.retry.policy.NeverRetryPolicy;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleRetryExceptionHandlerTests extends TestCase {
|
||||
|
||||
private RepeatContext context = new RepeatContextSupport(new RepeatContextSupport(null));
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
RepeatSynchronizationManager.register(context);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
protected void tearDown() throws Exception {
|
||||
RepeatSynchronizationManager.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.step.support.SimpleRetryExceptionHandler#handleException(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)}.
|
||||
*/
|
||||
public void testRethrowWhenRetryExhausted() {
|
||||
|
||||
RetryPolicy retryPolicy = new NeverRetryPolicy();
|
||||
RuntimeException ex = new RuntimeException("foo");
|
||||
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex);
|
||||
|
||||
// Then pretend to handle the exception in the parent context...
|
||||
try {
|
||||
handler.handleException(context.getParent(), ex);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals(ex, e);
|
||||
}
|
||||
|
||||
assertEquals(0, context.attributeNames().length);
|
||||
// One for the retry exhausted flag and one for the counter in the delegate exception handler
|
||||
assertEquals(2, context.getParent().attributeNames().length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.step.support.SimpleRetryExceptionHandler#handleException(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)}.
|
||||
*/
|
||||
public void testNoRethrowWhenRetryNotExhausted() {
|
||||
|
||||
RetryPolicy retryPolicy = new AlwaysRetryPolicy();
|
||||
RuntimeException ex = new RuntimeException("foo");
|
||||
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex);
|
||||
|
||||
// Then pretend to handle the exception in the parent context...
|
||||
handler.handleException(context.getParent(), ex);
|
||||
|
||||
assertEquals(0, context.attributeNames().length);
|
||||
assertEquals(0, context.getParent().attributeNames().length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryPolicy
|
||||
* @param ex
|
||||
* @return
|
||||
*/
|
||||
private SimpleRetryExceptionHandler getHandlerAfterRetry(RetryPolicy retryPolicy, RuntimeException ex) {
|
||||
|
||||
// Always rethrow if the retry is exhausted
|
||||
SimpleRetryExceptionHandler handler = new SimpleRetryExceptionHandler(retryPolicy, new SimpleLimitExceptionHandler(0));
|
||||
|
||||
// Simulate a failed retry...
|
||||
RetryContext retryContext = retryPolicy.open(null);
|
||||
retryPolicy.registerThrowable(retryContext, ex);
|
||||
handler.close(retryContext, null, ex);
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2006-2008 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.execution.step.support;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.file.FlatFileParseException;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class SkipLimitReadFailurePolicyTests extends TestCase {
|
||||
|
||||
private LimitCheckingItemSkipPolicy failurePolicy;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
List skippableExceptions = new ArrayList();
|
||||
skippableExceptions.add(FlatFileParseException.class);
|
||||
|
||||
failurePolicy = new LimitCheckingItemSkipPolicy(1, skippableExceptions);
|
||||
}
|
||||
|
||||
public void testLimitExceed(){
|
||||
try{
|
||||
failurePolicy.shouldSkip(new FlatFileParseException("", ""), 2);
|
||||
fail();
|
||||
}
|
||||
catch(SkipLimitExceededException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testNonSkippableException(){
|
||||
assertFalse(failurePolicy.shouldSkip(new FileNotFoundException(), 2));
|
||||
}
|
||||
|
||||
public void testSkip(){
|
||||
assertTrue(failurePolicy.shouldSkip(new FlatFileParseException("",""), 0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.execution.step.ItemOrientedStep;
|
||||
import org.springframework.batch.item.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class StatefulRetryStepFactoryBeanTests extends TestCase {
|
||||
|
||||
private StatefulRetryStepFactoryBean factory = new StatefulRetryStepFactoryBean();
|
||||
|
||||
private List recovered = new ArrayList();
|
||||
|
||||
private List processed = new ArrayList();
|
||||
|
||||
private SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
|
||||
new MapStepExecutionDao());
|
||||
|
||||
JobExecution jobExecution;
|
||||
|
||||
private ItemWriter processor = new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
processed.add((String) data);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
MapJobInstanceDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
|
||||
factory.setBeanName("step");
|
||||
|
||||
factory.setItemReader(new ListItemReader(new ArrayList()));
|
||||
factory.setItemWriter(processor);
|
||||
factory.setJobRepository(repository);
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
|
||||
JobSupport job = new JobSupport("jobName");
|
||||
job.setRestartable(true);
|
||||
JobParameters jobParameters = new JobParametersBuilder().addString("statefulTest", "make_this_unique").toJobParameters();
|
||||
jobExecution = repository.createJobExecution(job, jobParameters);
|
||||
jobExecution.setEndTime(new Date());
|
||||
|
||||
}
|
||||
|
||||
public void testType() throws Exception {
|
||||
assertEquals(Step.class, factory.getObjectType());
|
||||
}
|
||||
|
||||
public void testDefaultValue() throws Exception {
|
||||
assertTrue(factory.getObject() instanceof Step);
|
||||
}
|
||||
|
||||
public void testRecovery() throws Exception {
|
||||
factory.setItemRecoverer(new ItemRecoverer() {
|
||||
public boolean recover(Object item, Throwable cause) {
|
||||
recovered.add(item);
|
||||
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
List items = TransactionAwareProxyFactory.createTransactionalList();
|
||||
items.addAll(Arrays.asList(new String[] { "a", "b", "c" }));
|
||||
ItemReader provider = new ListItemReader(items) {
|
||||
int count = 0;
|
||||
public Object read() {
|
||||
count++;
|
||||
if (count == 2) {
|
||||
throw new RuntimeException("Temporary error - retry for success.");
|
||||
}
|
||||
return super.read();
|
||||
}
|
||||
};
|
||||
factory.setItemReader(provider);
|
||||
factory.setRetryLimit(10);
|
||||
ItemOrientedStep step = (ItemOrientedStep) factory.getObject();
|
||||
|
||||
step.execute(new StepExecution(step, jobExecution));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.execution.job.JobSupport;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.execution.step.ItemOrientedStep;
|
||||
import org.springframework.batch.item.AbstractItemReader;
|
||||
import org.springframework.batch.item.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
|
||||
public class StepExecutorInterruptionTests extends TestCase {
|
||||
|
||||
private ItemOrientedStep step;
|
||||
|
||||
private JobExecution jobExecution;
|
||||
|
||||
private AbstractItemWriter itemWriter;
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
MapJobInstanceDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
|
||||
JobRepository jobRepository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
|
||||
new MapStepExecutionDao());
|
||||
|
||||
JobSupport jobConfiguration = new JobSupport();
|
||||
step = new ItemOrientedStep("interruptedStep");
|
||||
jobConfiguration.addStep(step);
|
||||
jobConfiguration.setBeanName("testJob");
|
||||
jobExecution = jobRepository.createJobExecution(jobConfiguration, new JobParameters());
|
||||
step.setJobRepository(jobRepository);
|
||||
step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
itemWriter = new AbstractItemWriter() {
|
||||
public void write(Object item) throws Exception {
|
||||
}
|
||||
};
|
||||
step.setItemHandler(new SimpleItemHandler(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return null;
|
||||
}
|
||||
}, itemWriter));
|
||||
stepExecution = new StepExecution(step, jobExecution);
|
||||
}
|
||||
|
||||
public void testInterruptChunk() throws Exception {
|
||||
|
||||
Thread processingThread = createThread(stepExecution);
|
||||
|
||||
processingThread.start();
|
||||
Thread.sleep(100);
|
||||
processingThread.interrupt();
|
||||
|
||||
int count = 0;
|
||||
while (processingThread.isAlive() && count < 1000) {
|
||||
Thread.sleep(20);
|
||||
count++;
|
||||
}
|
||||
|
||||
assertTrue("Timed out waiting for step to be interrupted.", count < 1000);
|
||||
assertFalse(processingThread.isAlive());
|
||||
assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
|
||||
}
|
||||
|
||||
public void testInterruptStep() throws Exception {
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
// N.B, If we don't set the completion policy it might run forever
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(2));
|
||||
step.setChunkOperations(template);
|
||||
testInterruptChunk();
|
||||
}
|
||||
|
||||
public void testInterruptOnInterruptedException() throws Exception {
|
||||
|
||||
Thread processingThread = createThread(stepExecution);
|
||||
|
||||
step.setItemHandler(new SimpleItemHandler(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return null;
|
||||
}
|
||||
}, itemWriter));
|
||||
|
||||
// This simulates the unlikely sounding, but in practice all too common
|
||||
// in Bamboo situation where the thread is interrupted before the lock
|
||||
// is taken.
|
||||
step.setSynchronizer(new StepExecutionSynchronizer() {
|
||||
public void lock(StepExecution stepExecution) throws InterruptedException {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
public void release(StepExecution stepExecution) {
|
||||
}
|
||||
});
|
||||
|
||||
processingThread.start();
|
||||
Thread.sleep(100);
|
||||
|
||||
int count = 0;
|
||||
while (processingThread.isAlive() && count < 1000) {
|
||||
Thread.sleep(20);
|
||||
count++;
|
||||
}
|
||||
|
||||
assertTrue("Timed out waiting for step to be interrupted.", count < 1000);
|
||||
assertFalse(processingThread.isAlive());
|
||||
assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private Thread createThread(final StepExecution stepExecution) {
|
||||
step.setItemHandler(new SimpleItemHandler(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
// do something non-trivial (and not Thread.sleep())
|
||||
double foo = 1;
|
||||
for (int i = 2; i < 250; i++) {
|
||||
foo = foo * i;
|
||||
}
|
||||
|
||||
if (foo != 1) {
|
||||
return new Double(foo);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}, itemWriter));
|
||||
|
||||
Thread processingThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
}
|
||||
catch (JobInterruptedException e) {
|
||||
// do nothing...
|
||||
}
|
||||
}
|
||||
};
|
||||
return processingThread;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.step.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.execution.step.support.ThreadStepInterruptionPolicy;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.context.RepeatContextSupport;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ThreadStepInterruptionPolicyTests extends TestCase {
|
||||
|
||||
ThreadStepInterruptionPolicy policy = new ThreadStepInterruptionPolicy();
|
||||
private RepeatContext context = new RepeatContextSupport(null);;
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.executor.interrupt.ThreadStepInterruptionPolicy#checkInterrupted(org.springframework.batch.repeat.RepeatContext)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testCheckInterruptedNotComplete() throws Exception {
|
||||
policy.checkInterrupted(context);
|
||||
// no exception
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.executor.interrupt.ThreadStepInterruptionPolicy#checkInterrupted(org.springframework.batch.repeat.RepeatContext)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testCheckInterruptedComplete() throws Exception {
|
||||
context.setTerminateOnly();
|
||||
try {
|
||||
policy.checkInterrupted(context);
|
||||
fail("Expected StepInterruptedException");
|
||||
} catch (JobInterruptedException e) {
|
||||
// expected
|
||||
assertTrue(e.getMessage().indexOf("interrupt")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.execution.tasklet;
|
||||
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class TaskletAdapterTests extends TestCase {
|
||||
|
||||
private TaskletAdapter tasklet = new TaskletAdapter();
|
||||
private Object result = null;
|
||||
|
||||
public ExitStatus execute() {
|
||||
return ExitStatus.NOOP;
|
||||
}
|
||||
|
||||
public Object process() {
|
||||
return result ;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
tasklet.setTargetObject(this);
|
||||
tasklet.setTargetMethod("execute");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.tasklet.TaskletAdapter#execute()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testExecuteWithExitStatus() throws Exception {
|
||||
assertEquals(ExitStatus.NOOP, tasklet.execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.tasklet.TaskletAdapter#mapResult(java.lang.Object)}.
|
||||
*/
|
||||
public void testMapResultWithNull() throws Exception {
|
||||
tasklet.setTargetMethod("process");
|
||||
assertEquals(ExitStatus.FINISHED, tasklet.execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.tasklet.TaskletAdapter#mapResult(java.lang.Object)}.
|
||||
*/
|
||||
public void testMapResultWithNonNull() throws Exception {
|
||||
tasklet.setTargetMethod("process");
|
||||
this.result = "foo";
|
||||
assertEquals(ExitStatus.CONTINUABLE, tasklet.execute());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 test.jdbc.datasource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.config.AbstractFactoryBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class InitializingDataSourceFactoryBean extends AbstractFactoryBean {
|
||||
|
||||
private Resource[] initScripts;
|
||||
|
||||
private Resource destroyScript;
|
||||
|
||||
DataSource dataSource;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
* @see java.lang.Object#finalize()
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
initialized = false;
|
||||
logger.debug("finalize called");
|
||||
}
|
||||
|
||||
protected void destroyInstance(Object instance) throws Exception {
|
||||
try {
|
||||
doExecuteScript(destroyScript);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
|
||||
}
|
||||
else {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(dataSource);
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
protected Object createInstance() throws Exception {
|
||||
Assert.notNull(dataSource);
|
||||
if (!initialized) {
|
||||
try {
|
||||
doExecuteScript(destroyScript);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.debug("Could not execute destroy script [" + destroyScript + "]", e);
|
||||
}
|
||||
if (initScripts != null) {
|
||||
for (int i = 0; i < initScripts.length; i++) {
|
||||
Resource initScript = initScripts[i];
|
||||
doExecuteScript(initScript);
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private void doExecuteScript(final Resource scriptResource) {
|
||||
if (scriptResource == null || !scriptResource.exists())
|
||||
return;
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
|
||||
transactionTemplate.execute(new TransactionCallback() {
|
||||
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
String[] scripts;
|
||||
try {
|
||||
scripts = StringUtils.delimitedListToStringArray(stripComments(IOUtils.readLines(scriptResource
|
||||
.getInputStream())), ";");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BeanInitializationException("Cannot load script from [" + scriptResource + "]", e);
|
||||
}
|
||||
for (int i = 0; i < scripts.length; i++) {
|
||||
String script = scripts[i].trim();
|
||||
if (StringUtils.hasText(script)) {
|
||||
jdbcTemplate.execute(scripts[i]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private String stripComments(List list) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (Iterator iter = list.iterator(); iter.hasNext();) {
|
||||
String line = (String) iter.next();
|
||||
if (!line.startsWith("//") && !line.startsWith("--")) {
|
||||
buffer.append(line + "\n");
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
return DataSource.class;
|
||||
}
|
||||
|
||||
public void setInitScript(Resource initScript) {
|
||||
this.initScripts = new Resource[] { initScript };
|
||||
}
|
||||
|
||||
public void setInitScripts(Resource[] initScripts) {
|
||||
this.initScripts = initScripts;
|
||||
}
|
||||
|
||||
public void setDestroyScript(Resource destroyScript) {
|
||||
this.destroyScript = destroyScript;
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user