From 3909b751519944338aeaefd30ecc01e3a2e71b20 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Wed, 1 May 2013 12:47:45 -0400 Subject: [PATCH] BATCHADM-161 - Add Job Launching Gateway For reference see: https://jira.springsource.org/browse/BATCHADM-161 * Add XML Schema * Add Namespace Handler * Add Parser and Gateway classes * Add tests --- spring-batch-integration/pom.xml | 12 ++ .../xml/BatchIntegrationNamespaceHandler.java | 35 ++++ .../config/xml/JobLaunchingGatewayParser.java | 78 ++++++++ .../launch/JobLaunchingGateway.java | 85 +++++++++ .../launch/JobLaunchingMessageHandler.java | 8 +- .../main/resources/META-INF/spring.handlers | 1 + .../main/resources/META-INF/spring.schemas | 2 + .../main/resources/META-INF/spring.tooling | 4 + .../xml/spring-batch-integration-1.3.xsd | 135 ++++++++++++++ .../config/xml/spring-batch-integration.gif | Bin 0 -> 539 bytes .../JobLauncherParserTestsConfiguration.java | 28 +++ .../xml/JobLaunchingGatewayParserTests.java | 110 ++++++++++++ .../JobLaunchingGatewayIntegrationTests.java | 166 ++++++++++++++++++ .../launch/JobLaunchingGatewayTests.java | 65 +++++++ ...JobLaunchingGatewayParserTests-context.xml | 31 ++++ ...atewayParserTestsNoJobLauncher-context.xml | 26 +++ ...chingGatewayParserTestsRunning-context.xml | 31 ++++ ...TestsWithEnableBatchProcessing-context.xml | 30 ++++ .../config/xml/batch-setup-context.xml | 28 +++ ...unchingGatewayIntegrationTests-context.xml | 33 ++++ 20 files changed, 904 insertions(+), 4 deletions(-) create mode 100644 spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java create mode 100644 spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParser.java create mode 100644 spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingGateway.java create mode 100644 spring-batch-integration/src/main/resources/META-INF/spring.handlers create mode 100644 spring-batch-integration/src/main/resources/META-INF/spring.schemas create mode 100644 spring-batch-integration/src/main/resources/META-INF/spring.tooling create mode 100644 spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd create mode 100644 spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration.gif create mode 100644 spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLauncherParserTestsConfiguration.java create mode 100644 spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests.java create mode 100644 spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests.java create mode 100644 spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests-context.xml create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsNoJobLauncher-context.xml create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsRunning-context.xml create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsWithEnableBatchProcessing-context.xml create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/batch-setup-context.xml create mode 100644 spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests-context.xml diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index c11991565..2e7ed1bfa 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -108,6 +108,18 @@ spring-integration-core compile + + org.springframework.integration + spring-integration-test + ${spring.integration.version} + test + + + junit-dep + junit + + + org.springframework.integration spring-integration-jdbc diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java new file mode 100644 index 000000000..eaf47fd9f --- /dev/null +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/BatchIntegrationNamespaceHandler.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2013 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.config.xml; + +import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler; + +/** + * The namespace handler for the Spring Batch Integration namespace. + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +public class BatchIntegrationNamespaceHandler extends AbstractIntegrationNamespaceHandler { + + /* (non-Javadoc) + * @see org.springframework.beans.factory.xml.NamespaceHandler#init() + */ + public void init() { + this.registerBeanDefinitionParser("job-launching-gateway", new JobLaunchingGatewayParser()); + } +} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParser.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParser.java new file mode 100644 index 000000000..736a13652 --- /dev/null +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParser.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2013 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.config.xml; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.integration.launch.JobLaunchingGateway; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.config.xml.AbstractConsumerEndpointParser; +import org.springframework.integration.config.xml.IntegrationNamespaceUtils; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * The parser for the Job-Launching Gateway, which will instantiate a + * {@link JobLaunchingGatewayParser}. If no {@link JobLauncher} reference has + * been provided, this parse will use the use the globally registered bean + * 'jobLauncher'. + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +public class JobLaunchingGatewayParser extends AbstractConsumerEndpointParser { + + private static final Log logger = LogFactory.getLog(JobLaunchingGatewayParser.class); + + @Override + protected String getInputChannelAttributeName() { + return "request-channel"; + } + + @Override + protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { + + final BeanDefinitionBuilder jobLaunchingGatewayBuilder = + BeanDefinitionBuilder.genericBeanDefinition(JobLaunchingGateway.class); + + final String jobLauncher = element.getAttribute("job-launcher"); + + if (StringUtils.hasText(jobLauncher)) { + jobLaunchingGatewayBuilder.addConstructorArgReference(jobLauncher); + } + else { + if (logger.isDebugEnabled()) { + logger.debug("No jobLauncher specified, using default 'jobLauncher' reference instead."); + } + jobLaunchingGatewayBuilder.addConstructorArgReference("jobLauncher"); + } + + IntegrationNamespaceUtils.setValueIfAttributeDefined(jobLaunchingGatewayBuilder, element, "reply-timeout", "sendTimeout"); + + final String replyChannel = element.getAttribute("reply-channel"); + + if (StringUtils.hasText(replyChannel)) { + jobLaunchingGatewayBuilder.addPropertyReference("outputChannel", replyChannel); + } + + return jobLaunchingGatewayBuilder; + + } + +} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingGateway.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingGateway.java new file mode 100644 index 000000000..f3b08e8b8 --- /dev/null +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingGateway.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2013 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.launch; + +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobExecutionException; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.integration.Message; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; +import org.springframework.util.Assert; + +/** + * The {@link JobLaunchingGateway} is used to launch Batch Jobs. Internally it + * delegates to a {@link JobLaunchingMessageHandler}. + * + * @author Gunnar Hillert + * + * @since 1.3 + */ +public class JobLaunchingGateway extends AbstractReplyProducingMessageHandler { + + private final JobLaunchingMessageHandler jobLaunchingMessageHandler; + + /** + * Constructor taking a {@link JobLauncher} as parameter. + * + * @param storedProcExecutor Must not be null. + * + */ + public JobLaunchingGateway(JobLauncher jobLauncher) { + Assert.notNull(jobLauncher, "jobLauncher must not be null."); + this.jobLaunchingMessageHandler = new JobLaunchingMessageHandler(jobLauncher); + } + + /** + * Launches a Batch Job using the provided request {@link Message}. The payload + * of the {@link Message} must be an instance of {@link JobLaunchRequest}. + * + * @param The provided requestMessage must not be null. + * @return Generally a {@link JobExecution} will always be returned. An + * exception ({@link MessageHandlingException}) will only be thrown if there + * is a failure to start the job. The cause of the exception will be a + * {@link JobExecutionException}. + * + * @throws MessageHandlingException + */ + @Override + protected Object handleRequestMessage(Message requestMessage) { + + Assert.notNull(requestMessage, "The provided requestMessage must not be null."); + + final Object payload = requestMessage.getPayload(); + + Assert.isInstanceOf(JobLaunchRequest.class, payload, "The payload must be of type JobLaunchRequest."); + + final JobLaunchRequest jobLaunchRequest = (JobLaunchRequest) payload; + + final JobExecution jobExecution; + + try { + jobExecution = this.jobLaunchingMessageHandler.launch(jobLaunchRequest); + } catch (JobExecutionException e) { + throw new MessageHandlingException(requestMessage, e); + } + + return jobExecution; + + } + +} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingMessageHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingMessageHandler.java index 4e9f001c6..018adad69 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingMessageHandler.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/JobLaunchingMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 the original author or authors. + * Copyright 2006-2013 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. @@ -27,7 +27,8 @@ import org.springframework.integration.annotation.ServiceActivator; * Message handler which uses strategies to convert a Message into a job and a set of job parameters * @author Jonas Partner * @author Dave Syer - * + * @author Gunnar Hillert + * */ public class JobLaunchingMessageHandler implements JobLaunchRequestHandler { @@ -46,8 +47,7 @@ public class JobLaunchingMessageHandler implements JobLaunchRequestHandler { Job job = request.getJob(); JobParameters jobParameters = request.getJobParameters(); - JobExecution execution = jobLauncher.run(job, jobParameters); - return execution; + return jobLauncher.run(job, jobParameters); } } diff --git a/spring-batch-integration/src/main/resources/META-INF/spring.handlers b/spring-batch-integration/src/main/resources/META-INF/spring.handlers new file mode 100644 index 000000000..84912a6f7 --- /dev/null +++ b/spring-batch-integration/src/main/resources/META-INF/spring.handlers @@ -0,0 +1 @@ +http\://www.springframework.org/schema/batch-integration=org.springframework.batch.integration.config.xml.BatchIntegrationNamespaceHandler diff --git a/spring-batch-integration/src/main/resources/META-INF/spring.schemas b/spring-batch-integration/src/main/resources/META-INF/spring.schemas new file mode 100644 index 000000000..5261db6ee --- /dev/null +++ b/spring-batch-integration/src/main/resources/META-INF/spring.schemas @@ -0,0 +1,2 @@ +http\://www.springframework.org/schema/batch-integration/spring-batch-integration-1.3.xsd=org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd +http\://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd=org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd diff --git a/spring-batch-integration/src/main/resources/META-INF/spring.tooling b/spring-batch-integration/src/main/resources/META-INF/spring.tooling new file mode 100644 index 000000000..017292a7c --- /dev/null +++ b/spring-batch-integration/src/main/resources/META-INF/spring.tooling @@ -0,0 +1,4 @@ +# Tooling related information for the Spring Batch Integration namespace +http\://www.springframework.org/schema/integration/spring-batch-integration@name=Spring Batch Integration Namespace +http\://www.springframework.org/schema/integration/spring-batch-integration@prefix=batch-int +http\://www.springframework.org/schema/integration/spring-batch-integration@icon=org/springframework/batch/integration/config/xml/spring-batch-integration.gif diff --git a/spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd b/spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd new file mode 100644 index 000000000..cae6ba4ec --- /dev/null +++ b/spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration-1.3.xsd @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration.gif b/spring-batch-integration/src/main/resources/org/springframework/batch/integration/config/xml/spring-batch-integration.gif new file mode 100644 index 0000000000000000000000000000000000000000..210e0764fa4c1e5baebcdea156bc3f3e1f97a2c9 GIT binary patch literal 539 zcmZ?wbhEHb6krfwc*Xz%|NsB*n7VH6iaomzUp%y<^XRV5le@dm?CrjBr0?SXo|o4a z>{}Ri^GM%=bBkWz+y8vM?x%h3?+zusxj5zR@#^Jm-pe}!R`mow*jzjz+p;&)qBX&& zG1jmr&Ac*H`_zJhTu;?PU-d#?%_oZ!?=4DAaa1VqRO?H!xIQD{=A4w7g+5uX8WR(2 zrX<_tc8Bb5QRHvpiB8JU`8KTWP?thKQZD zFcaE=iuVx<>PO@dH?gn{*FclYXGfDn1BEP literal 0 HcmV?d00001 diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLauncherParserTestsConfiguration.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLauncherParserTestsConfiguration.java new file mode 100644 index 000000000..eb5f00473 --- /dev/null +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLauncherParserTestsConfiguration.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002-2013 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.config.xml; + +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.context.annotation.Configuration; + +/** + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +@Configuration +@EnableBatchProcessing +public class JobLauncherParserTestsConfiguration { + +} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests.java new file mode 100644 index 000000000..a74e7c5b1 --- /dev/null +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2002-2013 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.config.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Test; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.integration.launch.JobLaunchingMessageHandler; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.channel.AbstractMessageChannel; +import org.springframework.integration.core.MessagingTemplate; +import org.springframework.integration.endpoint.EventDrivenConsumer; +import org.springframework.integration.test.util.TestUtils; + +/** + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +public class JobLaunchingGatewayParserTests { + + private ConfigurableApplicationContext context; + + private EventDrivenConsumer consumer; + + @Test + public void testGatewayParser() throws Exception { + setUp("JobLaunchingGatewayParserTests-context.xml", getClass()); + + final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(this.consumer, "inputChannel", AbstractMessageChannel.class); + assertEquals("requestChannel", inputChannel.getComponentName()); + + final JobLaunchingMessageHandler jobLaunchingMessageHandler = TestUtils.getPropertyValue(this.consumer, "handler.jobLaunchingMessageHandler", JobLaunchingMessageHandler.class); + + assertNotNull(jobLaunchingMessageHandler); + + final MessagingTemplate messagingTemplate = TestUtils.getPropertyValue(this.consumer, "handler.messagingTemplate", MessagingTemplate.class); + final Long sendTimeout = TestUtils.getPropertyValue(messagingTemplate, "sendTimeout", Long.class); + + assertEquals("Wrong sendTimeout", Long.valueOf(123L), sendTimeout); + assertFalse(this.consumer.isRunning()); + } + + @Test + public void testJobLaunchingGatewayIsRunning() throws Exception { + setUp("JobLaunchingGatewayParserTestsRunning-context.xml", getClass()); + assertTrue(this.consumer.isRunning()); + + final MessagingTemplate messagingTemplate = TestUtils.getPropertyValue(this.consumer, "handler.messagingTemplate", MessagingTemplate.class); + final Long sendTimeout = TestUtils.getPropertyValue(messagingTemplate, "sendTimeout", Long.class); + + assertEquals("Wrong sendTimeout", Long.valueOf(-1L), sendTimeout); + } + + @Test + public void testJobLaunchingGatewayNoJobLauncher() throws Exception { + try { + setUp("JobLaunchingGatewayParserTestsNoJobLauncher-context.xml", getClass()); + } + catch(BeanCreationException e) { + assertEquals("No bean named 'jobLauncher' is defined", e.getCause().getMessage()); + return; + } + fail("Expected a NoSuchBeanDefinitionException to be thrown."); + } + + @Test + public void testJobLaunchingGatewayWithEnableBatchProcessing() throws Exception { + + setUp("JobLaunchingGatewayParserTestsWithEnableBatchProcessing-context.xml", getClass()); + final JobLaunchingMessageHandler jobLaunchingMessageHandler = TestUtils.getPropertyValue(this.consumer, "handler.jobLaunchingMessageHandler", JobLaunchingMessageHandler.class); + assertNotNull(jobLaunchingMessageHandler); + + final JobLauncher jobLauncher = TestUtils.getPropertyValue(jobLaunchingMessageHandler, "jobLauncher", JobLauncher.class); + assertNotNull(jobLauncher); + + } + + @After + public void tearDown(){ + if(context != null){ + context.close(); + } + } + + public void setUp(String name, Class cls){ + context = new ClassPathXmlApplicationContext(name, cls); + consumer = this.context.getBean("batchjobExecutor", EventDrivenConsumer.class); + } + +} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests.java new file mode 100644 index 000000000..879ceed94 --- /dev/null +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests.java @@ -0,0 +1,166 @@ +/* + * Copyright 2002-2013 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.launch; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +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.integration.JobSupport; +import org.springframework.batch.integration.step.TestTasklet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.MessageHeaders; +import org.springframework.integration.MessagingException; +import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class JobLaunchingGatewayIntegrationTests { + + @Autowired + @Qualifier("requests") + private MessageChannel requestChannel; + + @Autowired + @Qualifier("response") + private PollableChannel responseChannel; + + @Autowired + private TestTasklet tasklet; + + @Autowired + private Job testJob; + + private JobSupport job = new JobSupport("testJob"); + + @Before + public void setUp() { + Object message = ""; + while (message!=null) { + message = responseChannel.receive(10L); + } + } + + @Test + @DirtiesContext + @SuppressWarnings("unchecked") + public void testNoReply() { + GenericMessage trigger = new GenericMessage(new JobLaunchRequest(job, + new JobParameters())); + try { + requestChannel.send(trigger); + } + catch (MessagingException e) { + String message = e.getMessage(); + assertTrue("Wrong message: " + message, message.contains("replyChannel")); + } + Message executionMessage = (Message) responseChannel.receive(1000); + + assertNull("JobExecution message received when no return address set", executionMessage); + } + + @SuppressWarnings("unchecked") + @Test + @DirtiesContext + public void testReply() { + JobParametersBuilder builder = new JobParametersBuilder(); + builder.addString("dontclash", "12"); + Map map = new HashMap(); + map.put(MessageHeaders.REPLY_CHANNEL, "response"); + MessageHeaders headers = new MessageHeaders(map); + GenericMessage trigger = new GenericMessage(new JobLaunchRequest(job, + builder.toJobParameters()), headers); + requestChannel.send(trigger); + Message executionMessage = (Message) responseChannel.receive(1000); + + assertNotNull("No response received", executionMessage); + JobExecution execution = executionMessage.getPayload(); + assertNotNull("JobExecution not returned", execution); + } + + @Test + @DirtiesContext + @SuppressWarnings("unchecked") + public void testWrongPayload() { + + final Message stringMessage = MessageBuilder.withPayload("just text").build(); + + try { + requestChannel.send(stringMessage); + } + catch (MessageHandlingException e) { + String message = e.getCause().getMessage(); + assertTrue("Wrong message: " + message, message.contains("The payload must be of type JobLaunchRequest.")); + } + Message executionMessage = (Message) responseChannel.receive(1000); + + assertNull("JobExecution message received when no return address set", executionMessage); + } + + @Test + @DirtiesContext + @SuppressWarnings("unchecked") + public void testExceptionRaised() throws InterruptedException { + + this.tasklet.setFail(true); + + JobParametersBuilder builder = new JobParametersBuilder(); + builder.addString("dontclash", "12"); + Map map = new HashMap(); + map.put(MessageHeaders.REPLY_CHANNEL, "response"); + MessageHeaders headers = new MessageHeaders(map); + GenericMessage trigger = new GenericMessage(new JobLaunchRequest(testJob, + builder.toJobParameters()), headers); + requestChannel.send(trigger); + + Message executionMessage = (Message) responseChannel.receive(1000); + + assertNotNull("No response received", executionMessage); + + JobExecution execution = executionMessage.getPayload(); + assertNotNull("JobExecution not returned", execution); + + assertEquals(ExitStatus.FAILED.getExitCode(), execution.getExitStatus().getExitCode()); + + } +} diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java new file mode 100644 index 000000000..0765195d4 --- /dev/null +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2013 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.launch; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersInvalidException; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.integration.JobSupport; +import org.springframework.integration.Message; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.support.MessageBuilder; + +/** + * + * @author Gunnar Hillert + * @since 1.3 + * + */ +public class JobLaunchingGatewayTests { + + @Test + public void testExceptionRaised() throws Exception { + + final Message message = MessageBuilder.withPayload(new JobLaunchRequest(new JobSupport("testJob"), + new JobParameters())).build(); + + final JobLauncher jobLauncher = mock(JobLauncher.class); + when(jobLauncher.run(any(Job.class), any(JobParameters.class))) + .thenThrow(new JobParametersInvalidException("This is a JobExecutionException.")); + + JobLaunchingGateway jobLaunchingGateway = new JobLaunchingGateway(jobLauncher); + + try { + jobLaunchingGateway.handleMessage(message); + } + catch (MessageHandlingException e) { + assertEquals("This is a JobExecutionException.", e.getCause().getMessage()); + return; + } + + fail("Expecting a MessageHandlingException to be thrown."); + + } +} diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests-context.xml new file mode 100644 index 000000000..a74da9452 --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTests-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsNoJobLauncher-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsNoJobLauncher-context.xml new file mode 100644 index 000000000..9b7a982e9 --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsNoJobLauncher-context.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsRunning-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsRunning-context.xml new file mode 100644 index 000000000..06b3c25fb --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsRunning-context.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsWithEnableBatchProcessing-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsWithEnableBatchProcessing-context.xml new file mode 100644 index 000000000..18813924f --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/JobLaunchingGatewayParserTestsWithEnableBatchProcessing-context.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/batch-setup-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/batch-setup-context.xml new file mode 100644 index 000000000..459ca6bcb --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/config/xml/batch-setup-context.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests-context.xml b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests-context.xml new file mode 100644 index 000000000..880a4148c --- /dev/null +++ b/spring-batch-integration/src/test/resources/org/springframework/batch/integration/launch/JobLaunchingGatewayIntegrationTests-context.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file