diff --git a/spring-batch-integration/.classpath b/spring-batch-integration/.classpath index bbffa4c27..371bd2dea 100644 --- a/spring-batch-integration/.classpath +++ b/spring-batch-integration/.classpath @@ -1,14 +1,14 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/spring-batch-integration/.project b/spring-batch-integration/.project index b5952e578..695b024dd 100644 --- a/spring-batch-integration/.project +++ b/spring-batch-integration/.project @@ -20,11 +20,6 @@ - - org.maven.ide.eclipse.maven2Builder - - - org.eclipse.jem.workbench.JavaEMFNature diff --git a/spring-batch-integration/.settings/com.springsource.sts.config.flow.prefs b/spring-batch-integration/.settings/com.springsource.sts.config.flow.prefs index 275c4be73..38984f7ff 100644 --- a/spring-batch-integration/.settings/com.springsource.sts.config.flow.prefs +++ b/spring-batch-integration/.settings/com.springsource.sts.config.flow.prefs @@ -1,3 +1,5 @@ -#Sat Mar 27 12:17:33 GMT 2010 -//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/file/FileToMessagesJobIntegrationTests-context.xml=\r\n\r\n\r\n\r\n\r\n\r\n -eclipse.preferences.version=1 +#Thu Apr 08 11:36:17 BST 2010 +//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/file/FileToMessagesJobIntegrationTests-context.xml=\r\n\r\n\r\n\r\n\r\n\r\n +//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml=\n\n\n\n\n\n\n\n\n\n +//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/tasklet/StepGatewayIntegrationTests-context.xml=\n\n\n\n\n\n\n\n\n\n +eclipse.preferences.version=1 diff --git a/spring-batch-integration/.settings/org.eclipse.wst.common.component b/spring-batch-integration/.settings/org.eclipse.wst.common.component index 62ba7949e..849ec8679 100644 --- a/spring-batch-integration/.settings/org.eclipse.wst.common.component +++ b/spring-batch-integration/.settings/org.eclipse.wst.common.component @@ -1,7 +1,8 @@ - - - - - - - + + + + + + + + diff --git a/spring-batch-integration/.settings/org.springframework.ide.eclipse.beans.core.prefs b/spring-batch-integration/.settings/org.springframework.ide.eclipse.beans.core.prefs index a03e4a5ac..044687602 100644 --- a/spring-batch-integration/.settings/org.springframework.ide.eclipse.beans.core.prefs +++ b/spring-batch-integration/.settings/org.springframework.ide.eclipse.beans.core.prefs @@ -1,3 +1,4 @@ -#Wed May 06 08:20:22 BST 2009 -eclipse.preferences.version=1 -org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false +#Thu Apr 08 11:37:37 BST 2010 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false +org.springframework.ide.eclipse.beans.core.loadNamespaceHandlerFromClasspath=false diff --git a/spring-batch-integration/.springBeans b/spring-batch-integration/.springBeans index 3fd911e10..234caa683 100644 --- a/spring-batch-integration/.springBeans +++ b/spring-batch-integration/.springBeans @@ -1,27 +1,29 @@ - - - 1 - - - - - - - src/test/resources/job-execution-context.xml - src/test/resources/simple-job-launcher-context.xml - src/test/resources/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/file/ResourceSplitterIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/retry/TransactionalPollingIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/retry/RepeatTransactionalPollingIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/retry/RetryRepeatTransactionalPollingIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/SmokeTests-context.xml - src/test/resources/org/springframework/batch/integration/retry/RetryTransactionalPollingIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/item/MessagingGatewayIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/partition/VanillaIntegrationTests-context.xml - src/test/resources/org/springframework/batch/integration/async/AsyncItemProcessorMessagingGatewayTests-context.xml - - - - + + + 1 + + + + + + + src/test/resources/job-execution-context.xml + src/test/resources/simple-job-launcher-context.xml + src/test/resources/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/file/ResourceSplitterIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/retry/TransactionalPollingIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/retry/RepeatTransactionalPollingIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/retry/RetryRepeatTransactionalPollingIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/SmokeTests-context.xml + src/test/resources/org/springframework/batch/integration/retry/RetryTransactionalPollingIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/item/MessagingGatewayIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/partition/VanillaIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/async/AsyncItemProcessorMessagingGatewayTests-context.xml + src/test/resources/org/springframework/batch/integration/chunk/ChunkStepIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/file/FileToMessagesJobIntegrationTests-context.xml + src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml + + + + diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionReply.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionReply.java deleted file mode 100644 index 6990ae5c1..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionReply.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.integration.job; - -/** - * @author dsyer - * - */ -public class JobExecutionReply { - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionRequest.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionRequest.java deleted file mode 100644 index b9ba90360..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/JobExecutionRequest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.integration.job; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.JobExecution; - -/** - * Encapsulation of a request to execute a job execution through a message flow - * consisting of step handlers. A handler should pass the message on as it is, - * modifying the request properties as necessary. Generally a handler will - * execute a step as part of the {@link JobExecution} passed in, and should - * change the status to {@link BatchStatus#COMPLETED} if the step is successful - * (generally a handler cannot determine if the whole job execution is complete, - * so this is just information about the step).
- * - * If the incoming status is {@link BatchStatus#FAILED}, - * {@link BatchStatus#ABANDONED} or {@link BatchStatus#STOPPING} the request - * should be ignored by handlers (passed on without modification). - * - * @author Dave Syer - * - */ -public class JobExecutionRequest { - - private JobExecution jobExecution; - - private BatchStatus status; - - private Throwable throwable; - - /** - * @param jobExecution - */ - public JobExecutionRequest(JobExecution jobExecution) { - this.jobExecution = jobExecution; - status = jobExecution.getStatus(); - } - - /** - * @return the current job execution id - */ - public Long getJobId() { - return this.jobExecution.getJobId(); - } - - /** - * @return the current {@link BatchStatus} - */ - public BatchStatus getStatus() { - return status; - } - - /** - * Public setter for the status. - * @param status the status to set - */ - public void setStatus(BatchStatus status) { - this.status = status; - } - - /** - * @return true if there are errors - */ - public boolean hasErrors() { - return throwable != null; - } - - /** - * Public getter for the throwable. - * @return the throwable - */ - public Throwable getLastThrowable() { - return throwable; - } - - /** - * Public setter for the throwable. - * @param throwable the throwable to set - */ - public void registerThrowable(Throwable throwable) { - this.throwable = throwable; - } - - /** - * Public getter for the jobExecution. - * @return the jobExecution - */ - public JobExecution getJobExecution() { - return jobExecution; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return getClass().getSimpleName()+": "+jobExecution; - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/MessageOrientedStep.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/MessageOrientedStep.java deleted file mode 100644 index d13153fd7..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/MessageOrientedStep.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.integration.job; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobInterruptedException; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.UnexpectedJobExecutionException; -import org.springframework.batch.core.step.AbstractStep; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.beans.factory.annotation.Required; -import org.springframework.integration.channel.PollableChannel; -import org.springframework.integration.core.Message; -import org.springframework.integration.core.MessageChannel; -import org.springframework.integration.message.GenericMessage; -import org.springframework.util.Assert; - -/** - * @author Dave Syer - * - */ -public class MessageOrientedStep extends AbstractStep { - - /** - * Key in execution context for flag to say we are waiting. - */ - public static final String WAITING = MessageOrientedStep.class.getName() + ".WAITING"; - - private MessageChannel outputChannel; - - private PollableChannel source; - - private static long MINUTE = 1000 * 60; - - private long executionTimeout = 30*MINUTE ; - - private long pollingInterval = 5; - - /** - * Public setter for the execution timeout in minutes. Defaults to 30. - * @param executionTimeoutMinutes the timeout to set - */ - public void setExecutionTimeoutMinutes(int executionTimeoutMinutes) { - this.executionTimeout = executionTimeoutMinutes * MINUTE; - } - - /** - * Public setter for the execution timeout in milliseconds. Defaults to 30 minutes. - * @param executionTimeout - */ - public void setExecutionTimeout(long executionTimeout) { - this.executionTimeout = executionTimeout; - } - - /** - * Public setter for the polling interval in milliseconds while waiting for - * replies signalling the end of the step. Defaults to 5. - * @param pollingInterval the polling interval to set - */ - public void setPollingInterval(long pollingInterval) { - this.pollingInterval = pollingInterval; - } - - /** - * Public setter for the target. - * @param outputChannel the target to set - */ - @Required - public void setOutputChannel(MessageChannel outputChannel) { - this.outputChannel = outputChannel; - } - - /** - * Public setter for the source. - * @param source the source to set - */ - @Required - public void setInputChannel(PollableChannel source) { - this.source = source; - } - - /** - * @see AbstractStep#execute(StepExecution) - */ - @Override - protected void doExecute(StepExecution stepExecution) throws JobInterruptedException, - UnexpectedJobExecutionException { - - JobExecutionRequest request = new JobExecutionRequest(stepExecution.getJobExecution()); - - ExecutionContext executionContext = stepExecution.getExecutionContext(); - - if (executionContext.containsKey(WAITING)) { - // restart scenario: we are still waiting for a response - waitForReply(request.getJobId()); - } - else { - executionContext.putString(WAITING, "true"); - getJobRepository().updateExecutionContext(stepExecution); - outputChannel.send(new GenericMessage(request)); - waitForReply(request.getJobId()); - } - - stepExecution.setExitStatus(ExitStatus.COMPLETED); - - } - - /** - * @param expectedJobId - */ - private void waitForReply(Long expectedJobId) { - long timeout = pollingInterval; - long maxCount = executionTimeout / timeout; - long count = 0; - - while (count++ < maxCount) { - - @SuppressWarnings("unchecked") - Message message = (Message) source.receive(timeout); - - if (message != null) { - - JobExecutionRequest payload = message.getPayload(); - Long jobInstanceId = payload.getJobId(); - Assert.state(jobInstanceId != null, "Message did not contain job instance id."); - Assert.state(jobInstanceId.equals(expectedJobId), "Message contained wrong job instance id [" - + jobInstanceId + "] should have been [" + expectedJobId + "]."); - - if (payload.getStatus() == BatchStatus.COMPLETED) { - // One of the steps decided we were finished - // TODO: wait for all the other steps that might be - // executing concurrently? - break; - } - - if (payload.hasErrors()) { - rethrow(payload.getLastThrowable()); - } - - } - } - - if (count >= maxCount) { - throw new StepExecutionTimeoutException("Timed out waiting for steps to execute."); - } - } - - /** - * @param lastThrowable - */ - private static void rethrow(Throwable t) throws RuntimeException { - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - if (t instanceof Exception) { - throw new UnexpectedJobExecutionException("Unexpected checked exception thrown by step.", t); - } - throw (Error) t; - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionMessageHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionMessageHandler.java deleted file mode 100644 index 1953f409f..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionMessageHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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.integration.job; - -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.job.SimpleStepHandler; -import org.springframework.batch.core.job.StepHandler; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.beans.factory.annotation.Required; -import org.springframework.integration.annotation.MessageEndpoint; -import org.springframework.integration.annotation.ServiceActivator; - -/** - * @author Dave Syer - * - */ -@MessageEndpoint -public class StepExecutionMessageHandler { - - private Step step; - - private StepHandler stepHandler; - - /** - * Public setter for the {@link Step}. - * @param step the step to set - */ - @Required - public void setStep(Step step) { - this.step = step; - } - - /** - * Public setter for the {@link JobRepository} that is needed to manage the - * state of the batch meta domain (jobs, steps, executions) during the life - * of a job. - * - * @param jobRepository - */ - @Required - public void setJobRepository(JobRepository jobRepository) { - stepHandler = new SimpleStepHandler(jobRepository); - } - - @ServiceActivator - public JobExecutionRequest handle(JobExecutionRequest request) { - - // Hand off immediately if the job has already failed - if (isComplete(request)) { - return request; - } - - JobExecution jobExecution = request.getJobExecution(); - - try { - - stepHandler.handleStep(step, jobExecution); - // (the job might actually not be complete, but the stage is). - request.setStatus(BatchStatus.COMPLETED); - - } - catch (Exception e) { - handleFailure(request, e); - } - catch (Error e) { - handleFailure(request, e); - throw e; - } - - return request; - - } - - /** - * @param request - * @return - */ - private boolean isComplete(JobExecutionRequest request) { - return request.getStatus() == BatchStatus.FAILED || request.getStatus() == BatchStatus.ABANDONED - || request.getStatus() == BatchStatus.STOPPING; - } - - /** - * @param request - * @param e - */ - private void handleFailure(JobExecutionRequest request, Throwable e) { - request.registerThrowable(e); - request.setStatus(BatchStatus.FAILED); - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionTimeoutException.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionTimeoutException.java deleted file mode 100644 index 424a63dd0..000000000 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/job/StepExecutionTimeoutException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.integration.job; - -import org.springframework.batch.core.UnexpectedJobExecutionException; - -/** - * @author Dave Syer - * - */ -public class StepExecutionTimeoutException extends UnexpectedJobExecutionException { - - /** - * Constructs a new instance. - * - * @param msg the exception message. - * - */ - public StepExecutionTimeoutException(String msg) { - super(msg); - } - -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/step/DelegateStep.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/step/DelegateStep.java new file mode 100644 index 000000000..05ad14bdc --- /dev/null +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/step/DelegateStep.java @@ -0,0 +1,56 @@ +/* + * Copyright 2006-2010 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.integration.step; + +import org.springframework.batch.core.Step; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.step.AbstractStep; +import org.springframework.util.Assert; + +/** + * Provides a wrapper for an existing {@link Step}, delegating execution to it, + * but serving all other operations locally. + * + * @author Dave Syer + * + */ +public class DelegateStep extends AbstractStep { + + private Step delegate; + + /** + * @param delegate the delegate to set + */ + public void setDelegate(Step delegate) { + this.delegate = delegate; + } + + /** + * Check mandatory properties (delegate). + */ + @Override + public void afterPropertiesSet() throws Exception { + Assert.state(delegate!=null, "A delegate Step must be provided"); + super.afterPropertiesSet(); + } + + @Override + protected void doExecute(StepExecution stepExecution) throws Exception { + delegate.execute(stepExecution); + } + +} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepTests.java deleted file mode 100644 index 16940458b..000000000 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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.integration.job; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.core.BatchStatus; -import org.springframework.batch.core.ExitStatus; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.integration.JobRepositorySupport; -import org.springframework.beans.factory.annotation.Required; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.integration.channel.DirectChannel; -import org.springframework.integration.channel.PollableChannel; -import org.springframework.integration.channel.ThreadLocalChannel; -import org.springframework.integration.core.Message; -import org.springframework.integration.core.MessageChannel; -import org.springframework.integration.message.GenericMessage; -import org.springframework.integration.message.MessageHandler; -import org.springframework.util.ReflectionUtils; - -/** - * @author Dave Syer - * - */ -public class MessageOrientedStepTests { - - private MessageOrientedStep step = new MessageOrientedStep(); - - private JobExecution jobExecution; - - private DirectChannel requestChannel; - - private PollableChannel replyChannel; - - @Before - public void createStep() { - replyChannel = new ThreadLocalChannel(); - requestChannel = new DirectChannel(); - step.setName("step"); - step.setOutputChannel(requestChannel); - step.setInputChannel(replyChannel); - step.setStartLimit(10); - step.setJobRepository(new JobRepositorySupport()); - JobInstance jobInstance = new JobInstance(0L, new JobParameters(), "job"); - jobExecution = new JobExecution(jobInstance); - } - - @Test - public void testSetRequestChannel() { - Method method = ReflectionUtils.findMethod(MessageOrientedStep.class, "setOutputChannel", - new Class[] { MessageChannel.class }); - assertNotNull(method); - Annotation[] annotations = AnnotationUtils.getAnnotations(method); - assertEquals(1, annotations.length); - assertEquals(Required.class, annotations[0].annotationType()); - } - - @Test - public void testSetReplyChannel() { - Method method = ReflectionUtils.findMethod(MessageOrientedStep.class, "setInputChannel", - new Class[] { PollableChannel.class }); - assertNotNull(method); - Annotation[] annotations = AnnotationUtils.getAnnotations(method); - assertEquals(1, annotations.length); - assertEquals(Required.class, annotations[0].annotationType()); - } - - /** - * Test method for - * {@link org.springframework.batch.integration.job.MessageOrientedStep#execute(org.springframework.batch.core.StepExecution)} - * . - * @throws Exception - */ - @Test - public void testExecuteWithTimeout() throws Exception { - requestChannel.subscribe(new MessageHandler() { - public void handleMessage(Message message) { - } - }); - step.setExecutionTimeout(1000); - step.setPollingInterval(100); - StepExecution stepExecution = jobExecution.createStepExecution(step.getName()); - step.execute(stepExecution); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); - String message = stepExecution.getExitStatus().getExitDescription(); - assertTrue("Wrong message: " + message, message.contains("StepExecutionTimeoutException")); - } - - @Test - public void testVanillaExecute() throws Exception { - requestChannel.subscribe(new MessageHandler() { - public void handleMessage(Message message) { - JobExecutionRequest jobExecution = (JobExecutionRequest) message.getPayload(); - jobExecution.setStatus(BatchStatus.COMPLETED); - replyChannel.send(message); - } - }); - step.execute(jobExecution.createStepExecution(step.getName())); - } - - @Test - public void testExecuteWithFailure() throws Exception { - requestChannel.subscribe(new MessageHandler() { - public void handleMessage(Message message) { - JobExecutionRequest jobExecution = (JobExecutionRequest) message.getPayload(); - jobExecution.registerThrowable(new RuntimeException("Planned failure")); - replyChannel.send(message); - } - }); - StepExecution stepExecution = jobExecution.createStepExecution(step.getName()); - step.execute(stepExecution); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); - String message = stepExecution.getExitStatus().getExitDescription(); - assertTrue("Wrong message: " + message, message.contains("Planned failure")); - } - - @Test - public void testExecuteOnRestart() throws Exception { - JobExecutionRequest jobExecutionRequest = new JobExecutionRequest(jobExecution); - jobExecutionRequest.setStatus(BatchStatus.COMPLETED); - // Send a message to the reply channel to simulate step that we were - // waiting for when we failed on the last execution. - replyChannel.send(new GenericMessage(jobExecutionRequest)); - StepExecution stepExecution = jobExecution.createStepExecution(step.getName()); - stepExecution.getExecutionContext().putString(MessageOrientedStep.WAITING, "true"); - step.execute(stepExecution); - } - -} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/StepExecutionMessageHandlerTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/StepExecutionMessageHandlerTests.java deleted file mode 100644 index d50e8d669..000000000 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/StepExecutionMessageHandlerTests.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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.integration.job; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; - -import org.junit.Test; -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.StartLimitExceededException; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.integration.JobRepositorySupport; -import org.springframework.batch.integration.StepSupport; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.beans.factory.annotation.Required; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.util.ReflectionUtils; - -/** - * @author Dave Syer - * - */ -public class StepExecutionMessageHandlerTests { - - /** - * Test method for - * {@link org.springframework.batch.integration.job.StepExecutionMessageHandler#setStep(org.springframework.batch.core.Step)} - * . - */ - @Test - public void testSetStep() { - Method method = ReflectionUtils.findMethod(StepExecutionMessageHandler.class, "setStep", - new Class[] { Step.class }); - assertNotNull(method); - Annotation[] annotations = AnnotationUtils.getAnnotations(method); - assertEquals(1, annotations.length); - assertEquals(Required.class, annotations[0].annotationType()); - } - - /** - * Test method for - * {@link org.springframework.batch.integration.job.StepExecutionMessageHandler#setJobRepository(org.springframework.batch.core.repository.JobRepository)} - * . - */ - @Test - public void testSetJobRepository() { - Method method = ReflectionUtils.findMethod(StepExecutionMessageHandler.class, "setJobRepository", - new Class[] { JobRepository.class }); - assertNotNull(method); - Annotation[] annotations = AnnotationUtils.getAnnotations(method); - assertEquals(1, annotations.length); - assertEquals(Required.class, annotations[0].annotationType()); - } - - @Test - public void testVanillaHandle() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport(); - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecutionRequest message = handler.handle(new JobExecutionRequest(jobRepository.createJobExecution("job", - new JobParameters()))); - assertEquals(1, message.getJobExecution().getStepExecutions().size()); - assertEquals(BatchStatus.COMPLETED, message.getStatus()); - } - - @Test - public void testHandleWithInputs() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport(); - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecutionRequest jobExecutionRequest = new JobExecutionRequest(jobRepository.createJobExecution("job", - new JobParameters())); - jobExecutionRequest.getJobExecution().getExecutionContext().putString("foo", "bar"); - JobExecutionRequest message = handler.handle(jobExecutionRequest); - assertEquals(1, message.getJobExecution().getStepExecutions().size()); - JobExecution jobExecution = message.getJobExecution(); - assertTrue(jobExecution.getExecutionContext().containsKey("foo")); - } - - @Test - public void testHandleWithInputsAndOutputs() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport(); - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecutionRequest jobExecutionRequest = new JobExecutionRequest(jobRepository.createJobExecution("job", - new JobParameters())); - jobExecutionRequest.getJobExecution().getExecutionContext().putString("foo", "bar"); - // The step has to add the output attribute to the context - handler.setStep(new StepSupport("step") { - @Override - public void execute(StepExecution stepExecution) throws JobInterruptedException { - stepExecution.getJobExecution().getExecutionContext().putString("bar", "spam"); - } - }); - JobExecutionRequest message = handler.handle(jobExecutionRequest); - JobExecution jobExecution = message.getJobExecution(); - assertTrue(jobExecution.getExecutionContext().containsKey("foo")); - assertTrue(jobExecution.getExecutionContext().containsKey("bar")); - } - - @Test - public void testHandleFailedJob() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport(); - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - jobExecution.setStatus(BatchStatus.FAILED); - JobExecutionRequest message = handler.handle(new JobExecutionRequest(jobExecution)); - assertEquals(0, message.getJobExecution().getStepExecutions().size()); - } - - @Test - public void testHandleRestart() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport() { - @Override - public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) { - StepExecution stepExecution = new StepExecution(stepName, new JobExecution(jobInstance)); - stepExecution.setStatus(BatchStatus.FAILED); - stepExecution.setExecutionContext(new ExecutionContext() { - { - put("foo", "bar"); - } - }); - - return stepExecution; - } - - @Override - public int getStepExecutionCount(JobInstance jobInstance, String stepName) { - return 1; - } - }; - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - JobExecutionRequest message = handler.handle(new JobExecutionRequest(jobExecution)); - assertNotNull(message); - assertEquals(1, jobExecution.getStepExecutions().size()); - StepExecution stepExecution = (StepExecution) jobExecution.getStepExecutions().iterator().next(); - assertTrue(stepExecution.getExecutionContext().containsKey("foo")); - } - - @Test - public void testHandleRestartAlreadyComplete() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport() { - @Override - public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) { - StepExecution stepExecution = new StepExecution(stepName, new JobExecution(jobInstance)); - stepExecution.setStatus(BatchStatus.COMPLETED); - return stepExecution; - } - }; - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - JobExecutionRequest message = handler.handle(new JobExecutionRequest(jobExecution)); - assertNotNull(message); - assertEquals(0, jobExecution.getStepExecutions().size()); - assertEquals(BatchStatus.STARTING, jobExecution.getStatus()); - } - - @Test - public void testHandleRestartStartLimitExceeded() throws Exception { - JobRepositorySupport jobRepository = new JobRepositorySupport() { - @Override - public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) { - return new StepExecution(stepName, new JobExecution(jobInstance)); - } - - @Override - public int getStepExecutionCount(JobInstance jobInstance, String stepName) { - // sufficiently high restart count - return 100; - } - }; - StepExecutionMessageHandler handler = createHandler(jobRepository); - JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters()); - JobExecutionRequest message = handler.handle(new JobExecutionRequest(jobExecution)); - assertNotNull(message); - assertEquals(0, jobExecution.getStepExecutions().size()); - JobExecutionRequest payload = message; - assertEquals(BatchStatus.FAILED, payload.getStatus()); - assertTrue(payload.hasErrors()); - Throwable error = payload.getLastThrowable(); - assertTrue(error instanceof StartLimitExceededException); - String text = error.getMessage(); - assertTrue("Wrong exit description: " + text, text.toLowerCase().contains("start limit")); - } - - /** - * @param jobRepository - * @return a handler for step executions - * - */ - public StepExecutionMessageHandler createHandler(JobRepositorySupport jobRepository) { - StepExecutionMessageHandler handler = new StepExecutionMessageHandler(); - StepSupport step = new StepSupport("step"); - step.setStartLimit(10); - handler.setStep(step); - handler.setJobRepository(jobRepository); - return handler; - } - -} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/step/StepGatewayIntegrationTests.java similarity index 66% rename from spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests.java rename to spring-batch-integration/src/test/java/org/springframework/batch/integration/step/StepGatewayIntegrationTests.java index 40e2e245b..5569e76b1 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/step/StepGatewayIntegrationTests.java @@ -13,16 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.integration.job; +package org.springframework.batch.integration.step; import static org.junit.Assert.assertEquals; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.ExitStatus; 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.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -35,7 +38,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; */ @ContextConfiguration() @RunWith(SpringJUnit4ClassRunner.class) -public class MessageOrientedStepIntegrationTests { +public class StepGatewayIntegrationTests { @Autowired private JobLauncher jobLauncher; @@ -44,10 +47,27 @@ public class MessageOrientedStepIntegrationTests { @Qualifier("job") private Job job; + @Autowired + private TestTasklet tasklet; + + @After + public void clear() { + tasklet.setFail(false); + } + @Test public void testLaunchJob() throws Exception { JobExecution jobExecution = jobLauncher.run(job, new JobParameters()); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); + assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } + + @Test + public void testLaunchFailedJob() throws Exception { + tasklet.setFail(true); + JobExecution jobExecution = jobLauncher.run(job, new JobParametersBuilder().addLong("run.id", 2L).toJobParameters()); + assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); + assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus()); } } diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/TestTasklet.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/step/TestTasklet.java similarity index 80% rename from spring-batch-integration/src/test/java/org/springframework/batch/integration/job/TestTasklet.java rename to spring-batch-integration/src/test/java/org/springframework/batch/integration/step/TestTasklet.java index 6d99da878..3824ff1b3 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/job/TestTasklet.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/step/TestTasklet.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.integration.job; +package org.springframework.batch.integration.step; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; @@ -25,12 +25,17 @@ import org.springframework.batch.repeat.RepeatStatus; * */ public class TestTasklet implements Tasklet { + + private boolean fail = false; + + public void setFail(boolean fail) { + this.fail = fail; + } - /* - * (non-Javadoc) - * - */ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + if (fail) { + throw new IllegalStateException("Planned Tasklet failure"); + } return RepeatStatus.FINISHED; } diff --git a/spring-batch-integration/src/test/resources/log4j.properties b/spring-batch-integration/src/test/resources/log4j.properties index 8c5be0336..ed4cdc90c 100644 --- a/spring-batch-integration/src/test/resources/log4j.properties +++ b/spring-batch-integration/src/test/resources/log4j.properties @@ -4,6 +4,8 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %5p %t [%c] - <%m>%n -log4j.logger.org.springframework.batch.core=DEBUG +log4j.category.org.springframework.context=INFO +log4j.category.org.springframework.beans=INFO +log4j.category.org.springframework.batch.core=DEBUG log4j.category.org.springframework.integration=DEBUG -log4j.category.org.springframework.transaction=DEBUG \ No newline at end of file +log4j.category.org.springframework.transaction=INFO \ No newline at end of file diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests-context.xml deleted file mode 100644 index f1c86262e..000000000 --- a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/job/MessageOrientedStepIntegrationTests-context.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml index d10465146..0f7f85bc8 100644 --- a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingMessageHandlerIntegrationTests-context.xml @@ -26,7 +26,7 @@ - + \ No newline at end of file diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml new file mode 100644 index 000000000..633025d2a --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch-integration/src/test/resources/simple-job-launcher-context.xml b/spring-batch-integration/src/test/resources/simple-job-launcher-context.xml index 1f75530a3..b97a78764 100644 --- a/spring-batch-integration/src/test/resources/simple-job-launcher-context.xml +++ b/spring-batch-integration/src/test/resources/simple-job-launcher-context.xml @@ -38,22 +38,8 @@ - - - - - - - - - - - - - - - - + +