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
This commit is contained in:
committed by
Michael Minella
parent
f23dd64740
commit
3909b75151
@@ -108,6 +108,18 @@
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-test</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-jdbc</artifactId>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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} <em>must</em> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.springframework.org/schema/batch-integration=org.springframework.batch.integration.config.xml.BatchIntegrationNamespaceHandler
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
targetNamespace="http://www.springframework.org/schema/batch-integration"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration"
|
||||
schemaLocation="http://www.springframework.org/schema/integration/spring-integration.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Batch Integration
|
||||
Support.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="job-launching-gateway">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This Outbound Gateway is used to launch Batch Jobs. The
|
||||
payload of Messages to be processed MUST be an instance
|
||||
of JobLaunchRequest.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="corespringBatchIntegrationComponentAttributes"/>
|
||||
<xsd:attribute name="request-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The input Message Channel of this endpoint.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="reply-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Message Channel to which the resulting JobExecution
|
||||
payload will be sent.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="reply-timeout" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Allows you to specify how long this gateway will wait for
|
||||
the reply message to be sent successfully to the reply channel
|
||||
before throwing an exception. This attribute only applies when the
|
||||
channel might block, for example when using a bounded queue channel that
|
||||
is currently full.
|
||||
|
||||
Also, keep in mind that when sending to a DirectChannel, the
|
||||
invocation will occur in the sender's thread. Therefore,
|
||||
the failing of the send operation may be caused by other
|
||||
components further downstream.
|
||||
|
||||
The "reply-timeout" attribute maps to the "sendTimeout" property of the
|
||||
underlying 'MessagingTemplate' instance (org.springframework.integration.core.MessagingTemplate).
|
||||
|
||||
The attribute will default, if not specified, to '-1', meaning that
|
||||
by default, the Gateway will wait indefinitely. The value is
|
||||
specified in milliseconds.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="job-launcher" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation><![CDATA[
|
||||
Pass in a custom JobLauncher bean reference.
|
||||
This attribute is optional. If not specified the
|
||||
adapter will re-use the default instance (under
|
||||
the id 'jobLauncher', e.g. when using the
|
||||
@EnableBatchProcessing annotation via JavaConfig).
|
||||
If no default instance exists an exception is
|
||||
thrown.
|
||||
]]></xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.batch.core.launch.JobLauncher" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the order for invocation when this endpoint
|
||||
is connected as a subscriber to a SubscribableChannel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:attributeGroup name="corespringBatchIntegrationComponentAttributes">
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Identifies the underlying Spring bean definition, which is an
|
||||
instance of either 'EventDrivenConsumer' or 'PollingConsumer',
|
||||
depending on whether the component's input channel is a
|
||||
'SubscribableChannel' or 'PollableChannel'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-startup" default="true" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Flag to indicate that the component should start automatically
|
||||
on startup (default true).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
</xsd:schema>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 539 B |
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<JobLaunchRequest> trigger = new GenericMessage<JobLaunchRequest>(new JobLaunchRequest(job,
|
||||
new JobParameters()));
|
||||
try {
|
||||
requestChannel.send(trigger);
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Wrong message: " + message, message.contains("replyChannel"));
|
||||
}
|
||||
Message<JobExecution> executionMessage = (Message<JobExecution>) 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<String, Object> map = new HashMap<String, Object>();
|
||||
map.put(MessageHeaders.REPLY_CHANNEL, "response");
|
||||
MessageHeaders headers = new MessageHeaders(map);
|
||||
GenericMessage<JobLaunchRequest> trigger = new GenericMessage<JobLaunchRequest>(new JobLaunchRequest(job,
|
||||
builder.toJobParameters()), headers);
|
||||
requestChannel.send(trigger);
|
||||
Message<JobExecution> executionMessage = (Message<JobExecution>) 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<String> 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<JobExecution> executionMessage = (Message<JobExecution>) 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<String, Object> map = new HashMap<String, Object>();
|
||||
map.put(MessageHeaders.REPLY_CHANNEL, "response");
|
||||
MessageHeaders headers = new MessageHeaders(map);
|
||||
GenericMessage<JobLaunchRequest> trigger = new GenericMessage<JobLaunchRequest>(new JobLaunchRequest(testJob,
|
||||
builder.toJobParameters()), headers);
|
||||
requestChannel.send(trigger);
|
||||
|
||||
Message<JobExecution> executionMessage = (Message<JobExecution>) responseChannel.receive(1000);
|
||||
|
||||
assertNotNull("No response received", executionMessage);
|
||||
|
||||
JobExecution execution = executionMessage.getPayload();
|
||||
assertNotNull("JobExecution not returned", execution);
|
||||
|
||||
assertEquals(ExitStatus.FAILED.getExitCode(), execution.getExitStatus().getExitCode());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<JobLaunchRequest> 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.");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns:batch-int="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
|
||||
|
||||
<import resource="batch-setup-context.xml"/>
|
||||
|
||||
<int:channel id="requestChannel"/>
|
||||
<int:channel id="replyChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
|
||||
<batch-int:job-launching-gateway id="batchjobExecutor" reply-timeout="123"
|
||||
auto-startup="false"
|
||||
request-channel="requestChannel"
|
||||
reply-channel="replyChannel"
|
||||
job-launcher="jobLauncher"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns:batch-int="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
|
||||
|
||||
<import resource="batch-setup-context.xml"/>
|
||||
|
||||
<int:channel id="requestChannel"/>
|
||||
<int:channel id="replyChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<batch-int:job-launching-gateway id="batchjobExecutor"
|
||||
auto-startup="true"
|
||||
request-channel="requestChannel"
|
||||
reply-channel="replyChannel"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns:batch-int="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
|
||||
|
||||
<import resource="batch-setup-context.xml"/>
|
||||
|
||||
<int:channel id="requestChannel"/>
|
||||
<int:channel id="replyChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
|
||||
<batch-int:job-launching-gateway id="batchjobExecutor"
|
||||
auto-startup="true"
|
||||
request-channel="requestChannel"
|
||||
reply-channel="replyChannel"
|
||||
job-launcher="jobLauncher"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns:batch-int="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
|
||||
http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
|
||||
<bean class="org.springframework.batch.integration.config.xml.JobLauncherParserTestsConfiguration"/>
|
||||
|
||||
<int:channel id="requestChannel"/>
|
||||
<int:channel id="replyChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<batch-int:job-launching-gateway id="batchjobExecutor"
|
||||
auto-startup="true"
|
||||
request-channel="requestChannel"
|
||||
reply-channel="replyChannel"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
xmlns:batch-int="http://www.springframework.org/schema/batch-integration"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL"/>
|
||||
|
||||
<jdbc:initialize-database data-source="dataSource">
|
||||
<jdbc:script location="classpath:/org/springframework/batch/core/schema-drop-hsqldb.sql"/>
|
||||
<jdbc:script location="classpath:/org/springframework/batch/core/schema-hsqldb.sql"/>
|
||||
</jdbc:initialize-database>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<batch:job-repository data-source="dataSource" id="jobRepository"
|
||||
transaction-manager="transactionManager" table-prefix="BATCH_"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:batch-integration="http://www.springframework.org/schema/batch-integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/batch-integration http://www.springframework.org/schema/batch-integration/spring-batch-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
<import resource="classpath:simple-job-launcher-context.xml" />
|
||||
<integration:annotation-config/>
|
||||
<integration:channel id="requests" />
|
||||
<integration:channel id="response">
|
||||
<integration:queue/>
|
||||
</integration:channel>
|
||||
|
||||
<batch-integration:job-launching-gateway request-channel="requests" job-launcher="jobLauncher" />
|
||||
|
||||
<bean id="testJob" parent="simpleJob">
|
||||
<property name="steps" ref="step" />
|
||||
</bean>
|
||||
<bean id="step" parent="taskletStep">
|
||||
<property name="tasklet" ref="tasklet"/>
|
||||
</bean>
|
||||
|
||||
<bean id="tasklet" class="org.springframework.batch.integration.step.TestTasklet" />
|
||||
</beans>
|
||||
Reference in New Issue
Block a user