OPEN - issue BATCH-791: Ditch Tasklet (StepHandler is more flexible)
Done. Use StepHandler instead.
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.step.tasklet;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -22,22 +22,19 @@ import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
public class CallableTaskletAdapterTests {
|
||||
|
||||
private CallableTaskletAdapter adapter = new CallableTaskletAdapter();
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.step.tasklet.CallableTaskletAdapter#execute()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public class CallableStepHandlerAdapterTests {
|
||||
|
||||
private CallableStepHandlerAdapter adapter = new CallableStepHandlerAdapter();
|
||||
|
||||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
public void testHandle() throws Exception {
|
||||
adapter.setCallable(new Callable<ExitStatus>() {
|
||||
public ExitStatus call() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
});
|
||||
assertEquals(ExitStatus.FINISHED, adapter.execute());
|
||||
assertEquals(ExitStatus.FINISHED, adapter.handle(null,null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.step.handler.ConfigurableSystemProcessExitCodeMapper;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigurableSystemProcessExitCodeMapper}
|
||||
*/
|
||||
public class ConfigurableSystemProcessExitCodeMapperTests {
|
||||
|
||||
private ConfigurableSystemProcessExitCodeMapper mapper = new ConfigurableSystemProcessExitCodeMapper();
|
||||
|
||||
/**
|
||||
* Regular usage scenario - mapping adheres to injected values
|
||||
*/
|
||||
@Test
|
||||
public void testMapping() {
|
||||
Map<Object, ExitStatus> mappings = new HashMap<Object, ExitStatus>() {{
|
||||
put(0, ExitStatus.FINISHED);
|
||||
put(1, ExitStatus.FAILED);
|
||||
put(2, ExitStatus.CONTINUABLE);
|
||||
put(3, ExitStatus.NOOP);
|
||||
put(4, ExitStatus.UNKNOWN);
|
||||
put(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY, ExitStatus.UNKNOWN);
|
||||
}};
|
||||
|
||||
mapper.setMappings(mappings);
|
||||
|
||||
//check explicitly defined values
|
||||
for (Map.Entry<Object, ExitStatus> entry : mappings.entrySet()) {
|
||||
if (entry.getKey().equals(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY)) continue;
|
||||
|
||||
int exitCode = (Integer) entry.getKey();
|
||||
assertSame(entry.getValue(), mapper.getExitStatus(exitCode));
|
||||
}
|
||||
|
||||
//check the else clause
|
||||
assertSame(mappings.get(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY),
|
||||
mapper.getExitStatus(5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Else clause is required in the injected map - setter checks its presence.
|
||||
*/
|
||||
@Test
|
||||
public void testSetMappingsMissingElseClause() {
|
||||
Map<Object, ExitStatus> missingElse = new HashMap<Object, ExitStatus>();
|
||||
try {
|
||||
mapper.setMappings(missingElse);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
Map<Object, ExitStatus> containsElse = new HashMap<Object, ExitStatus>() {{
|
||||
put(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY, ExitStatus.FAILED);
|
||||
}};
|
||||
// no error expected now
|
||||
mapper.setMappings(containsElse);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,8 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.step.item;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import org.springframework.batch.core.step.handler.StepHandler;
|
||||
import org.springframework.batch.core.step.item.ItemOrientedStepHandler;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.support.PassthroughItemProcessor;
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Tests for {@link SimpleSystemProcessExitCodeMapper}.
|
||||
*/
|
||||
public class SimpleSystemProcessExitCodeMapperTests {
|
||||
|
||||
private SimpleSystemProcessExitCodeMapper mapper = new SimpleSystemProcessExitCodeMapper();
|
||||
|
||||
/**
|
||||
* 0 -> ExitStatus.FINISHED
|
||||
* else -> ExitStatus.FAILED
|
||||
*/
|
||||
@Test
|
||||
public void testMapping() {
|
||||
assertEquals(ExitStatus.FINISHED, mapper.getExitStatus(0));
|
||||
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(1));
|
||||
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(-1));
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.core.step.item;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.core.repository.support.SimpleJobRepository;
|
||||
import org.springframework.batch.core.step.StepExecutionSynchronizer;
|
||||
import org.springframework.batch.core.step.handler.StepHandlerStep;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.step.tasklet;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -25,9 +25,9 @@ import org.springframework.batch.repeat.ExitStatus;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class TaskletAdapterTests {
|
||||
public class StepHandlerAdapterTests {
|
||||
|
||||
private TaskletAdapter tasklet = new TaskletAdapter();
|
||||
private StepHandlerAdapter tasklet = new StepHandlerAdapter();
|
||||
private Object result = null;
|
||||
|
||||
public ExitStatus execute() {
|
||||
@@ -38,41 +38,28 @@ public class TaskletAdapterTests {
|
||||
return result ;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
tasklet.setTargetObject(this);
|
||||
tasklet.setTargetMethod("execute");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.step.tasklet.TaskletAdapter#execute()}.
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteWithExitStatus() throws Exception {
|
||||
assertEquals(ExitStatus.NOOP, tasklet.execute());
|
||||
tasklet.setTargetMethod("execute");
|
||||
assertEquals(ExitStatus.NOOP, tasklet.handle(null,null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.step.tasklet.TaskletAdapter#mapResult(java.lang.Object)}.
|
||||
*/
|
||||
@Test
|
||||
public void testMapResultWithNull() throws Exception {
|
||||
tasklet.setTargetMethod("process");
|
||||
assertEquals(ExitStatus.FINISHED, tasklet.execute());
|
||||
assertEquals(ExitStatus.FINISHED, tasklet.handle(null,null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.step.tasklet.TaskletAdapter#mapResult(java.lang.Object)}.
|
||||
*/
|
||||
@Test
|
||||
public void testMapResultWithNonNull() throws Exception {
|
||||
tasklet.setTargetMethod("process");
|
||||
this.result = "foo";
|
||||
assertEquals(ExitStatus.FINISHED, tasklet.execute());
|
||||
assertEquals(ExitStatus.FINISHED, tasklet.handle(null,null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.step.item;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -39,6 +39,7 @@ import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
|
||||
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
|
||||
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.handler.StepHandlerStep;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
@@ -14,15 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.core.step.item;
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
@@ -42,6 +47,7 @@ import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
|
||||
import org.springframework.batch.core.repository.support.SimpleJobRepository;
|
||||
import org.springframework.batch.core.step.JobRepositorySupport;
|
||||
import org.springframework.batch.core.step.StepInterruptionPolicy;
|
||||
import org.springframework.batch.core.step.handler.StepHandlerStep;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
@@ -58,7 +64,7 @@ import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
|
||||
public class StepHandlerStepTests extends TestCase {
|
||||
public class StepHandlerStepTests {
|
||||
|
||||
List<String> processed = new ArrayList<String>();
|
||||
|
||||
@@ -99,7 +105,8 @@ public class StepHandlerStepTests extends TestCase {
|
||||
return step;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MapJobInstanceDao.clear();
|
||||
MapStepExecutionDao.clear();
|
||||
MapJobExecutionDao.clear();
|
||||
@@ -119,6 +126,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStepExecutor() throws Exception {
|
||||
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
@@ -133,6 +141,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
/**
|
||||
* StepExecution should be updated after every chunk commit.
|
||||
*/
|
||||
@Test
|
||||
public void testStepExecutionUpdates() throws Exception {
|
||||
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
@@ -153,6 +162,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
/**
|
||||
* Failure to update StepExecution after chunk commit is fatal.
|
||||
*/
|
||||
@Test
|
||||
public void testStepExecutionUpdateFailure() throws Exception {
|
||||
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
@@ -175,6 +185,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
|
||||
SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
|
||||
@@ -188,6 +199,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(1, processed.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementRollbackCount() {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -211,6 +223,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitCodeDefaultClassification() throws Exception {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -235,6 +248,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitCodeCustomClassification() throws Exception {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -270,6 +284,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
* make sure a job that has never been executed before, but does have
|
||||
* saveExecutionAttributes = true, doesn't have restoreFrom called on it.
|
||||
*/
|
||||
@Test
|
||||
public void testNonRestartedJob() throws Exception {
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
step.setStepHandler(new SimpleStepHandler<String>(tasklet, itemWriter));
|
||||
@@ -283,6 +298,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertTrue(tasklet.isGetExecutionAttributesCalled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulExecutionWithExecutionContext() throws Exception {
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution(step.getName(), jobExecution);
|
||||
@@ -299,6 +315,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(3, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulExecutionWithFailureOnSaveOfExecutionContext() throws Exception {
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution(step.getName(), jobExecution);
|
||||
@@ -328,6 +345,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
* set to false, doesn't have restore or getExecutionAttributes called on
|
||||
* it.
|
||||
*/
|
||||
@Test
|
||||
public void testNoSaveExecutionAttributesRestartableJob() {
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
step.setStepHandler(new SimpleStepHandler<String>(tasklet, itemWriter));
|
||||
@@ -349,6 +367,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
* nothing will be restored because the Tasklet does not implement
|
||||
* Restartable.
|
||||
*/
|
||||
@Test
|
||||
public void testRestartJobOnNonRestartableTasklet() throws Exception {
|
||||
step.setStepHandler(new SimpleStepHandler<String>(new ItemReader<String>() {
|
||||
public String read() throws Exception {
|
||||
@@ -361,6 +380,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
step.execute(stepExecution);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStreamManager() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public String read() throws Exception {
|
||||
@@ -385,6 +405,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectlyInjectedItemStream() throws Exception {
|
||||
step.setStreams(new ItemStream[] { new ItemStreamSupport() {
|
||||
public void update(ExecutionContext executionContext) {
|
||||
@@ -401,6 +422,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectlyInjectedListener() throws Exception {
|
||||
step.registerStepExecutionListener(new StepExecutionListenerSupport() {
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
@@ -418,6 +440,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(2, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListenerCalledBeforeStreamOpened() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
@@ -435,6 +458,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterStep() throws Exception {
|
||||
|
||||
final ExitStatus customStatus = new ExitStatus(false, "custom code");
|
||||
@@ -459,6 +483,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(customStatus.getExitDescription(), returnedStatus.getExitDescription());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectlyInjectedListenerOnError() throws Exception {
|
||||
step.registerStepExecutionListener(new StepExecutionListenerSupport() {
|
||||
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
|
||||
@@ -483,6 +508,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectlyInjectedStreamWhichIsAlsoReader() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public String read() throws Exception {
|
||||
@@ -507,6 +533,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
assertEquals("bar", stepExecution.getExecutionContext().getString("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForInterruptedException() {
|
||||
|
||||
StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy() {
|
||||
@@ -546,6 +573,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForNormalFailure() throws Exception {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -573,6 +601,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForErrorFailure() throws Exception {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -600,6 +629,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForResetFailedException() throws Exception {
|
||||
|
||||
ItemReader<String> itemReader = new ItemReader<String>() {
|
||||
@@ -635,6 +665,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForCommitFailedException() throws Exception {
|
||||
|
||||
step.setTransactionManager(new ResourcelessTransactionManager() {
|
||||
@@ -665,6 +696,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForFinalUpdateFailedException() throws Exception {
|
||||
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
@@ -693,6 +725,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusForCloseFailedException() throws Exception {
|
||||
|
||||
MockRestartableItemReader itemReader = new MockRestartableItemReader() {
|
||||
@@ -732,6 +765,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
* commiting first chunk - otherwise ItemStreams won't recognize it is
|
||||
* restart scenario on next run.
|
||||
*/
|
||||
@Test
|
||||
public void testRestartAfterFailureInFirstChunk() throws Exception {
|
||||
MockRestartableItemReader reader = new MockRestartableItemReader() {
|
||||
public String read() throws Exception {
|
||||
@@ -756,6 +790,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStepToCompletion() throws Exception {
|
||||
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
@@ -777,6 +812,7 @@ public class StepHandlerStepTests extends TestCase {
|
||||
* causes step to fail.
|
||||
* @throws JobInterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testStepFailureInAfterStepCallback() throws JobInterruptedException {
|
||||
StepExecutionListener listener = new StepExecutionListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
@@ -0,0 +1,212 @@
|
||||
package org.springframework.batch.core.step.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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.repeat.ExitStatus;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Tests for {@link SystemCommandStepHandler}.
|
||||
*/
|
||||
public class SystemCommandStepHandlerIntegrationTests {
|
||||
|
||||
private static final Log log = LogFactory.getLog(SystemCommandStepHandlerIntegrationTests.class);
|
||||
|
||||
private SystemCommandStepHandler tasklet = new SystemCommandStepHandler();
|
||||
|
||||
private StepExecution stepExecution = new StepExecution("systemCommandStep", new JobExecution(new JobInstance(
|
||||
1L, new JobParameters(), "systemCommandJob")));
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
tasklet.setEnvironmentParams(null); // inherit from parent process
|
||||
tasklet.setWorkingDirectory(null); // inherit from parent process
|
||||
tasklet.setSystemProcessExitCodeMapper(new TestExitCodeMapper());
|
||||
tasklet.setTimeout(5000); // long enough timeout
|
||||
tasklet.setTerminationCheckInterval(500);
|
||||
tasklet.setCommand("invalid command, change value for successful execution");
|
||||
tasklet.afterPropertiesSet();
|
||||
|
||||
tasklet.beforeStep(stepExecution);
|
||||
}
|
||||
|
||||
/*
|
||||
* Regular usage scenario - successful execution of system command.
|
||||
*/
|
||||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
String command = "java -version";
|
||||
tasklet.setCommand(command);
|
||||
tasklet.afterPropertiesSet();
|
||||
|
||||
log.info("Executing command: " + command);
|
||||
ExitStatus exitStatus = tasklet.handle(null,null);
|
||||
|
||||
assertEquals(ExitStatus.FINISHED, exitStatus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Failed execution scenario - error exit code returned by system command.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteFailure() throws Exception {
|
||||
String command = "java org.springframework.batch.sample.tasklet.UnknownClass";
|
||||
tasklet.setCommand(command);
|
||||
tasklet.afterPropertiesSet();
|
||||
|
||||
log.info("Executing command: " + command);
|
||||
ExitStatus exitStatus = tasklet.handle(null,null);
|
||||
|
||||
assertEquals(ExitStatus.FAILED, exitStatus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Failed execution scenario - execution time exceeds timeout.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteTimeout() throws Exception {
|
||||
String command = "sleep 3";
|
||||
tasklet.setCommand(command);
|
||||
tasklet.setTimeout(10);
|
||||
tasklet.afterPropertiesSet();
|
||||
|
||||
log.info("Executing command: " + command);
|
||||
try {
|
||||
tasklet.handle(null,null);
|
||||
fail();
|
||||
}
|
||||
catch (SystemCommandException e) {
|
||||
assertTrue(e.getMessage().indexOf("did not finish successfully within the timeout") > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Job interrupted scenario.
|
||||
*/
|
||||
@Test
|
||||
public void testInterruption() throws Exception {
|
||||
String command = "sleep 5";
|
||||
tasklet.setCommand(command);
|
||||
tasklet.setTerminationCheckInterval(10);
|
||||
tasklet.afterPropertiesSet();
|
||||
|
||||
stepExecution.setTerminateOnly();
|
||||
try {
|
||||
tasklet.handle(null,null);
|
||||
fail();
|
||||
}
|
||||
catch (JobInterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
assertTrue(e.getMessage().indexOf("Job interrupted while executing system command") > -1);
|
||||
assertTrue(e.getMessage().indexOf(command) > -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Command property value is required to be set.
|
||||
*/
|
||||
@Test
|
||||
public void testCommandNotSet() throws Exception {
|
||||
tasklet.setCommand(null);
|
||||
try {
|
||||
tasklet.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
tasklet.setCommand("");
|
||||
try {
|
||||
tasklet.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Timeout must be set to non-zero value.
|
||||
*/
|
||||
@Test
|
||||
public void testTimeoutNotSet() throws Exception {
|
||||
tasklet.setCommand("not-empty placeholder");
|
||||
tasklet.setTimeout(0);
|
||||
try {
|
||||
tasklet.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Working directory property must point to an existing location and it must
|
||||
* be a directory
|
||||
*/
|
||||
@Test
|
||||
public void testWorkingDirectory() throws Exception {
|
||||
File notExistingFile = new File("not-existing-path");
|
||||
Assert.state(!notExistingFile.exists());
|
||||
|
||||
try {
|
||||
tasklet.setWorkingDirectory(notExistingFile.getCanonicalPath());
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
File notDirectory = File.createTempFile(this.getClass().getName(), null);
|
||||
Assert.state(notDirectory.exists());
|
||||
Assert.state(!notDirectory.isDirectory());
|
||||
|
||||
try {
|
||||
tasklet.setWorkingDirectory(notDirectory.getCanonicalPath());
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
File directory = notDirectory.getParentFile();
|
||||
Assert.state(directory.exists());
|
||||
Assert.state(directory.isDirectory());
|
||||
|
||||
// no error expected now
|
||||
tasklet.setWorkingDirectory(directory.getCanonicalPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit code mapper containing mapping logic expected by the tests. 0 means
|
||||
* finished successfully, other value means failure.
|
||||
*/
|
||||
private static class TestExitCodeMapper implements SystemProcessExitCodeMapper {
|
||||
|
||||
public ExitStatus getExitStatus(int exitCode) {
|
||||
if (exitCode == 0) {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
else {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
package org.springframework.batch.core.step.tasklet;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
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.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepExecutionListener;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
|
||||
import org.springframework.batch.core.step.JobRepositorySupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
public class TaskletStepTests extends TestCase {
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
private List<Serializable> list = new ArrayList<Serializable>();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
stepExecution = new StepExecution("stepName", new JobExecution(new JobInstance(new Long(0L),
|
||||
new JobParameters(), "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, contains(message.toLowerCase(), "tasklet"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testRepositoryMandatory() throws Exception {
|
||||
TaskletStep step = new TaskletStep();
|
||||
try {
|
||||
step.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain 'mandatory': " + message, contains(message.toLowerCase(), "mandatory"));
|
||||
}
|
||||
}
|
||||
|
||||
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 updateExecutionContext(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 updateExecutionContext(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.setStepExecutionListeners(new StepExecutionListener[] { new StepExecutionListenerSupport() {
|
||||
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.getExitCode(), stepExecution.getExitStatus().getExitCode());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void testExceptionError() throws JobInterruptedException, UnexpectedJobExecutionException {
|
||||
TaskletStep step = new TaskletStep(new StubTasklet(new Error("Foo!")), new JobRepositorySupport());
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (Error e) {
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When job is interrupted the {@link JobInterruptedException} should be
|
||||
* propagated up.
|
||||
*/
|
||||
public void testJobInterrupted() throws Exception {
|
||||
TaskletStep step = new TaskletStep(new Tasklet() {
|
||||
public ExitStatus execute() throws Exception {
|
||||
throw new JobInterruptedException("Job interrupted while executing tasklet");
|
||||
}
|
||||
}, new JobRepositorySupport());
|
||||
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (JobInterruptedException expected) {
|
||||
assertEquals("Job interrupted while executing tasklet", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception in {@link StepExecutionListener#afterStep(StepExecution)}
|
||||
* causes step to fail.
|
||||
* @throws JobInterruptedException
|
||||
*/
|
||||
public void testStepFailureInAfterStepCallback() throws JobInterruptedException {
|
||||
TaskletStep step = new TaskletStep(new Tasklet() {
|
||||
public ExitStatus execute() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
}, new JobRepositorySupport());
|
||||
|
||||
StepExecutionListener listener = new StepExecutionListenerSupport() {
|
||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
||||
throw new RuntimeException("exception thrown in afterStep to signal failure");
|
||||
}
|
||||
};
|
||||
step.setStepExecutionListeners(new StepExecutionListener[] { listener });
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (RuntimeException expected) {
|
||||
assertEquals("exception thrown in afterStep to signal failure", expected.getMessage());
|
||||
}
|
||||
|
||||
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
|
||||
|
||||
}
|
||||
|
||||
private static class StubTasklet extends StepExecutionListenerSupport implements Tasklet {
|
||||
|
||||
private final boolean exitFailure;
|
||||
|
||||
private final boolean throwException;
|
||||
|
||||
private final boolean assertStepContext;
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
private Throwable exception = null;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param error
|
||||
*/
|
||||
public StubTasklet(Throwable error) {
|
||||
this(false, false, false);
|
||||
this.exception = error;
|
||||
}
|
||||
|
||||
public ExitStatus execute() throws Exception {
|
||||
if (throwException) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
if (exception!=null) {
|
||||
if (exception instanceof Exception) throw (Exception) exception;
|
||||
if (exception instanceof Error) throw (Error) exception;
|
||||
}
|
||||
|
||||
if (exitFailure) {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
if (assertStepContext) {
|
||||
assertNotNull(this.stepExecution);
|
||||
}
|
||||
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
this.stepExecution = stepExecution;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user