INT-2275: any outbound-channel-adapter in <chain>
Add re-init logic for nested chains Add logic about nested element for AbstractChannelAdapterParser Refactor of DefaultOutboundChannelAdapterParser Test for non-last nested chain with some outbound-channel-adapter Improve XSD for chain-type Manual outbound-channel-adapter ability for chain Integration tests for all outbound-channel-adapter within <chain> Remove redundant 'return-value-required' attribute from <stored-proc-outbound-channel-adapter> Add support 'expectReply' for FileWritingMessageHandler INT-2275 polishing & refactor FileOutbound*Parser HttpRequestExecutingMessageHandlerTests polishing INT-2275: polishing JavaDoc
This commit is contained in:
committed by
Oleg Zhurakousky
parent
4d5b8d5be1
commit
45c429ee2b
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -54,6 +54,7 @@ import java.nio.charset.Charset;
|
||||
* @author Iwein Fuld
|
||||
* @author Alex Peters
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class FileWritingMessageHandler extends AbstractReplyProducingMessageHandler {
|
||||
|
||||
@@ -71,6 +72,7 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
|
||||
|
||||
private volatile Charset charset = Charset.defaultCharset();
|
||||
|
||||
private volatile boolean expectReply = true;
|
||||
|
||||
public FileWritingMessageHandler(File destinationDirectory) {
|
||||
Assert.notNull(destinationDirectory, "Destination directory must not be null.");
|
||||
@@ -92,7 +94,15 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
|
||||
public void setTemporaryFileSuffix(String temporaryFileSuffix) {
|
||||
this.temporaryFileSuffix = temporaryFileSuffix;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify whether a reply Message is expected. If not, this handler will simply return null for a
|
||||
* successful response or throw an Exception for a non-successful response. The default is true.
|
||||
*/
|
||||
public void setExpectReply(boolean expectReply) {
|
||||
this.expectReply = expectReply;
|
||||
}
|
||||
|
||||
protected String getTemporaryFileSuffix() {
|
||||
return temporaryFileSuffix;
|
||||
}
|
||||
@@ -169,6 +179,11 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(requestMessage, "failed to write Message payload to file", e);
|
||||
}
|
||||
|
||||
if (!this.expectReply) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (resultFile != null) {
|
||||
if (originalFileFromHeader == null && payload instanceof File) {
|
||||
return MessageBuilder.withPayload(resultFile)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -22,8 +22,6 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <outbound-channel-adapter/> element of the 'file'
|
||||
@@ -32,36 +30,14 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Iwein Fuld
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class FileOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder handlerBuilder = FileWritingMessageHandlerBeanDefinitionBuilder.configure(
|
||||
element, IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME, parserContext);
|
||||
if (handlerBuilder != null){
|
||||
String remoteFileNameGenerator = element.getAttribute("filename-generator");
|
||||
String remoteFileNameGeneratorExpression = element.getAttribute("filename-generator-expression");
|
||||
boolean hasRemoteFileNameGenerator = StringUtils.hasText(remoteFileNameGenerator);
|
||||
boolean hasRemoteFileNameGeneratorExpression = StringUtils.hasText(remoteFileNameGeneratorExpression);
|
||||
if (hasRemoteFileNameGenerator || hasRemoteFileNameGeneratorExpression) {
|
||||
if (hasRemoteFileNameGenerator && hasRemoteFileNameGeneratorExpression) {
|
||||
parserContext.getReaderContext().error("at most one of 'filename-generator-expression' or 'filename-generator' " +
|
||||
"is allowed on file outbound adapter/gateway", element);
|
||||
}
|
||||
if (hasRemoteFileNameGenerator) {
|
||||
handlerBuilder.addPropertyReference("fileNameGenerator", remoteFileNameGenerator);
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder fileNameGeneratorBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.file.DefaultFileNameGenerator");
|
||||
fileNameGeneratorBuilder.addPropertyValue("expression", remoteFileNameGeneratorExpression);
|
||||
handlerBuilder.addPropertyValue("fileNameGenerator", fileNameGeneratorBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (handlerBuilder != null ? handlerBuilder.getBeanDefinition() : null);
|
||||
BeanDefinitionBuilder handlerBuilder = FileWritingMessageHandlerBeanDefinitionBuilder.configure(element, false, parserContext);
|
||||
return handlerBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -16,18 +16,19 @@
|
||||
|
||||
package org.springframework.integration.file.config;
|
||||
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the 'outbound-gateway' element of the file namespace.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @since 1.0.3
|
||||
*/
|
||||
public class FileOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
@@ -39,31 +40,8 @@ public class FileOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
String replyChannel = element.getAttribute("reply-channel");
|
||||
|
||||
BeanDefinitionBuilder handlerBuilder =
|
||||
FileWritingMessageHandlerBeanDefinitionBuilder.configure(element, replyChannel, parserContext);
|
||||
|
||||
String remoteFileNameGenerator = element.getAttribute("filename-generator");
|
||||
String remoteFileNameGeneratorExpression = element.getAttribute("filename-generator-expression");
|
||||
boolean hasRemoteFileNameGenerator = StringUtils.hasText(remoteFileNameGenerator);
|
||||
boolean hasRemoteFileNameGeneratorExpression = StringUtils.hasText(remoteFileNameGeneratorExpression);
|
||||
if (hasRemoteFileNameGenerator || hasRemoteFileNameGeneratorExpression) {
|
||||
if (hasRemoteFileNameGenerator && hasRemoteFileNameGeneratorExpression) {
|
||||
parserContext.getReaderContext().error("at most one of 'filename-generator-expression' or 'filename-generator' " +
|
||||
"is allowed on file outbound adapter/gateway", element) ;
|
||||
}
|
||||
if (hasRemoteFileNameGenerator) {
|
||||
handlerBuilder.addPropertyReference("fileNameGenerator", remoteFileNameGenerator);
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder fileNameGeneratorBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.file.DefaultFileNameGenerator");
|
||||
fileNameGeneratorBuilder.addPropertyValue("expression", remoteFileNameGeneratorExpression);
|
||||
handlerBuilder.addPropertyValue("fileNameGenerator", fileNameGeneratorBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder handlerBuilder = FileWritingMessageHandlerBeanDefinitionBuilder.configure(element, true, parserContext);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(handlerBuilder, element, "reply-channel", "outputChannel");
|
||||
return handlerBuilder;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.integration.file.config;
|
||||
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -29,32 +30,42 @@ import org.springframework.util.StringUtils;
|
||||
* {@link org.springframework.integration.file.FileWritingMessageHandler}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @since 1.0.3
|
||||
*/
|
||||
abstract class FileWritingMessageHandlerBeanDefinitionBuilder {
|
||||
|
||||
static BeanDefinitionBuilder configure(Element element, String outputChannelBeanName, ParserContext parserContext) {
|
||||
if (outputChannelBeanName == null) {
|
||||
parserContext.getReaderContext().error("outputChannelBeanName must not be null", element);
|
||||
return null;
|
||||
}
|
||||
static BeanDefinitionBuilder configure(Element element, boolean expectReply, ParserContext parserContext) {
|
||||
|
||||
String directory = element.getAttribute("directory");
|
||||
if (!StringUtils.hasText(directory)) {
|
||||
parserContext.getReaderContext().error("directory is required", element);
|
||||
}
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.integration.file.config.FileWritingMessageHandlerFactoryBean");
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FileWritingMessageHandlerFactoryBean.class);
|
||||
builder.addPropertyValue("directory", directory);
|
||||
if (StringUtils.hasText(outputChannelBeanName)) {
|
||||
builder.addPropertyReference("outputChannel", outputChannelBeanName);
|
||||
}
|
||||
builder.addPropertyValue("expectReply", expectReply);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-create-directory");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "delete-source-files");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "temporary-file-suffix");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
String fileNameGenerator = element.getAttribute("filename-generator");
|
||||
if (StringUtils.hasText(fileNameGenerator)) {
|
||||
builder.addPropertyReference("fileNameGenerator", fileNameGenerator);
|
||||
String remoteFileNameGenerator = element.getAttribute("filename-generator");
|
||||
String remoteFileNameGeneratorExpression = element.getAttribute("filename-generator-expression");
|
||||
boolean hasRemoteFileNameGenerator = StringUtils.hasText(remoteFileNameGenerator);
|
||||
boolean hasRemoteFileNameGeneratorExpression = StringUtils.hasText(remoteFileNameGeneratorExpression);
|
||||
if (hasRemoteFileNameGenerator || hasRemoteFileNameGeneratorExpression) {
|
||||
if (hasRemoteFileNameGenerator && hasRemoteFileNameGeneratorExpression) {
|
||||
parserContext.getReaderContext().error("at most one of 'filename-generator-expression' or 'filename-generator' " +
|
||||
"is allowed on file outbound adapter/gateway", element);
|
||||
}
|
||||
if (hasRemoteFileNameGenerator) {
|
||||
builder.addPropertyReference("fileNameGenerator", remoteFileNameGenerator);
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder fileNameGeneratorBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(DefaultFileNameGenerator.class);
|
||||
fileNameGeneratorBuilder.addPropertyValue("expression", remoteFileNameGeneratorExpression);
|
||||
builder.addPropertyValue("fileNameGenerator", fileNameGeneratorBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.integration.file.FileWritingMessageHandler;
|
||||
* @author Iwein Fuld
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @since 1.0.3
|
||||
*/
|
||||
public class FileWritingMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerFactoryBean<FileWritingMessageHandler>{
|
||||
@@ -48,7 +49,9 @@ public class FileWritingMessageHandlerFactoryBean extends AbstractSimpleMessageH
|
||||
private volatile Long sendTimeout;
|
||||
|
||||
private volatile String temporaryFileSuffix;
|
||||
|
||||
|
||||
private volatile boolean expectReply = true;
|
||||
|
||||
public void setDirectory(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
@@ -80,7 +83,11 @@ public class FileWritingMessageHandlerFactoryBean extends AbstractSimpleMessageH
|
||||
public void setTemporaryFileSuffix(String temporaryFileSuffix) {
|
||||
this.temporaryFileSuffix = temporaryFileSuffix;
|
||||
}
|
||||
|
||||
|
||||
public void setExpectReply(boolean expectReply) {
|
||||
this.expectReply = expectReply;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileWritingMessageHandler createHandler() {
|
||||
FileWritingMessageHandler handler = new FileWritingMessageHandler(this.directory);
|
||||
@@ -105,6 +112,7 @@ public class FileWritingMessageHandlerFactoryBean extends AbstractSimpleMessageH
|
||||
if (this.temporaryFileSuffix != null) {
|
||||
handler.setTemporaryFileSuffix(this.temporaryFileSuffix);
|
||||
}
|
||||
handler.setExpectReply(this.expectReply);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:context="http://www.springframework.org/schema/context"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:file="http://www.springframework.org/schema/integration/file"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/file
|
||||
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd">
|
||||
|
||||
|
||||
<si:chain input-channel="outboundChainChannel">
|
||||
<si:header-enricher>
|
||||
<si:header name="#{T(org.springframework.integration.file.FileHeaders).FILENAME}" value="${test.file}"/>
|
||||
</si:header-enricher>
|
||||
<file:outbound-channel-adapter directory="${work.dir}"/>
|
||||
</si:chain>
|
||||
|
||||
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties" value="#{T(org.springframework.integration.file.FileOutboundChannelAdapterInsideChainTests).placeholderProperties}"/>
|
||||
</bean>
|
||||
|
||||
<context:property-placeholder properties-ref="placeholderProperties"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.integration.file;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* //INT-2275
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class FileOutboundChannelAdapterInsideChainTests {
|
||||
|
||||
public static final String TEST_FILE_NAME = FileOutboundChannelAdapterInsideChainTests.class.getSimpleName();
|
||||
|
||||
public static final String WORK_DIR_NAME = System.getProperty("java.io.tmpdir") + "/" + FileOutboundChannelAdapterInsideChainTests.class.getSimpleName() + "Dir";
|
||||
|
||||
public static final String SAMPLE_CONTENT = "test";
|
||||
|
||||
public static Properties placeholderProperties = new Properties();
|
||||
|
||||
static {
|
||||
placeholderProperties.put("test.file", TEST_FILE_NAME);
|
||||
placeholderProperties.put("work.dir", WORK_DIR_NAME);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private MessageChannel outboundChainChannel;
|
||||
|
||||
private static File workDir;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupClass() {
|
||||
workDir = new File(WORK_DIR_NAME);
|
||||
workDir.mkdir();
|
||||
workDir.deleteOnExit();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
if (workDir != null && workDir.exists()) {
|
||||
for (File file : workDir.listFiles()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
workDir.delete();
|
||||
}
|
||||
|
||||
@Test //INT-2275
|
||||
public void testFileOutboundChannelAdapterWithinChain() throws IOException {
|
||||
Message<String> message = MessageBuilder.withPayload(SAMPLE_CONTENT).build();
|
||||
outboundChainChannel.send(message);
|
||||
File testFile = new File(workDir, TEST_FILE_NAME);
|
||||
assertTrue(testFile.exists());
|
||||
byte[] testFileContent = FileCopyUtils.copyToByteArray(testFile);
|
||||
assertEquals(new String(testFileContent), SAMPLE_CONTENT);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user