Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
INT-2822: 'requires-reply' for outbound gateways
* Add `requires-reply` attribute for all adapters outbound gateways as `true` by default
* WS-outbound-gateway is still without it, because it has its own specific attribute `ignore-empty-responses`
* Make `requires-reply` as `false` by default for `jdbc:stored-proc-outbound-gateway` inasmuch as `jdbc:stored-proc-outbound-adapter`
doesn't have ability to configure `returning-resultset`
* add parser tests for `requires-reply`

JIRA: https://jira.springsource.org/browse/INT-2822
  • Loading branch information
artembilan committed Aug 16, 2013
1 parent 4018c30 commit f1fba65
Show file tree
Hide file tree
Showing 41 changed files with 256 additions and 59 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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
Expand Down Expand Up @@ -29,6 +29,7 @@
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Artem Bilan
*
* @since 2.1
*/
Expand All @@ -53,6 +54,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "routing-key");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "routing-key-expression");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "return-channel");

Expand Down
Expand Up @@ -199,6 +199,15 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="requires-reply" type="xsd:string" use="optional" default="true">
<xsd:annotation>
<xsd:documentation>
Specify whether this outbound gateway must return a non-null value. This value is
'true' by default, and a ReplyRequiredException will be thrown when
the underlying service returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Expand Down
Expand Up @@ -40,6 +40,7 @@
routing-key="si.test.binding"
amqp-template="amqpTemplate"
order="5"
requires-reply="false"
mapped-request-headers="foo*"
mapped-reply-headers="bar*"/>

Expand Down
Expand Up @@ -15,7 +15,12 @@
*/
package org.springframework.integration.amqp.config;

<<<<<<< HEAD
import static org.junit.Assert.assertEquals;
=======
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
>>>>>>> de75475... INT-2822: 'requires-reply' for outbound gateways
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
Expand Down Expand Up @@ -62,7 +67,7 @@ public void testGatewayConfig(){
Object edc = context.getBean("rabbitGateway");
AmqpOutboundEndpoint gateway = TestUtils.getPropertyValue(edc, "handler", AmqpOutboundEndpoint.class);
assertEquals(5, gateway.getOrder());
assertTrue(context.containsBean("rabbitGateway"));
assertTrue(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class));
assertEquals(context.getBean("fromRabbit"), TestUtils.getPropertyValue(gateway, "outputChannel"));
assertEquals("amqp:outbound-gateway", gateway.getComponentType());
MessageChannel returnChannel = context.getBean("returnChannel", MessageChannel.class);
Expand All @@ -81,6 +86,8 @@ public void withHeaderMapperCustomRequestResponse() {

AmqpOutboundEndpoint endpoint = TestUtils.getPropertyValue(eventDrivernConsumer, "handler", AmqpOutboundEndpoint.class);

assertFalse(TestUtils.getPropertyValue(endpoint, "requiresReply", Boolean.class));

Field amqpTemplateField = ReflectionUtils.findField(AmqpOutboundEndpoint.class, "amqpTemplate");
amqpTemplateField.setAccessible(true);
RabbitTemplate amqpTemplate = TestUtils.getPropertyValue(endpoint, "amqpTemplate", RabbitTemplate.class);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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.
Expand All @@ -26,6 +26,7 @@
* Base class for url-based outbound gateway parsers.
*
* @author Mark Fisher
* @author Artem Bilan
*/
public abstract class AbstractOutboundGatewayParser extends AbstractConsumerEndpointParser {

Expand All @@ -45,6 +46,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
if (StringUtils.hasText(replyChannel)) {
builder.addPropertyReference("replyChannel", replyChannel);
}
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply");
this.postProcessGateway(builder, element, parserContext);
return builder;
}
Expand Down
Expand Up @@ -1083,10 +1083,8 @@
<xsd:annotation>
<xsd:documentation>
Specify whether the service method must return a non-null value. This value will be
FALSE by
default, but if set to TRUE, a MessageHandlingException will be thrown when
the underlying service method (or
expression) returns a NULL value.
'false' by default, but if set to 'true', a ReplyRequiredException will be thrown when
the underlying service method (or expression) returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
Expand Down Expand Up @@ -3153,9 +3151,9 @@ is provided, the return value is expected to match a channel name exactly.
<xsd:attribute name="requires-reply" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
Specify whether the splitter method must return a non-null value. This value will be
FALSE by default, but if set to TRUE, a MessageHandlingException will be thrown when
the underlying service method (or expression) returns a NULL value.
Specify whether the service method must return a non-null value. This value will be
'false' by default, but if set to 'true', a ReplyRequiredException will be thrown when
the underlying service method (or expression) returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
Expand Down
Expand Up @@ -27,6 +27,7 @@
* @author Gary Russell
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Artem Bilan
*
* @since 2.1
*/
Expand Down Expand Up @@ -59,8 +60,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "local-directory");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-create-local-directory");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "order");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "rename-expression");
return builder;
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "rename-expression"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply"); return builder;
}

protected void configureFilter(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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.
Expand Down Expand Up @@ -44,6 +44,7 @@ protected String getInputChannelAttributeName() {
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinitionBuilder handlerBuilder = FileWritingMessageHandlerBeanDefinitionBuilder.configure(element, true, parserContext);
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "reply-timeout", "sendTimeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "requires-reply");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(handlerBuilder, element, "reply-channel", "outputChannel");
return handlerBuilder;
}
Expand Down
Expand Up @@ -394,6 +394,15 @@ Only files matching this regular expression will be picked up by this adapter.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="requires-reply" type="xsd:string" use="optional" default="true">
<xsd:annotation>
<xsd:documentation>
Specify whether this outbound gateway must return a non-null value. This value is
'true' by default, and a ReplyRequiredException will be thrown when
the underlying service returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Expand Down
Expand Up @@ -19,7 +19,7 @@

<int-file:outbound-gateway id="gatewayWithDirectoryExpression"
request-channel="someChannel" directory-expression="'build/foo'"
auto-startup="false" order="777" filename-generator-expression="'foo.txt'">
auto-startup="false" order="777" filename-generator-expression="'foo.txt'" requires-reply="false">
<int-file:request-handler-advice-chain>
<beans:bean class="org.springframework.integration.file.config.FileOutboundGatewayParserTests$FooAdvice" />
</int-file:request-handler-advice-chain>
Expand All @@ -28,7 +28,7 @@
<int-file:outbound-gateway id="gatewayWithReplaceMode"
request-channel="gatewayWithReplaceModeChannel"
filename-generator-expression="'fileToAppend.txt'" mode="REPLACE"
directory="test" />
directory="test" requires-reply="false"/>

<int-file:outbound-gateway id="gatewayWithAppendMode"
request-channel="gatewayWithAppendModeChannel"
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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.
Expand All @@ -17,6 +17,7 @@
package org.springframework.integration.file.config;

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;
Expand All @@ -27,10 +28,12 @@
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.expression.Expression;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.file.DefaultFileNameGenerator;
Expand All @@ -45,6 +48,7 @@
/**
* @author Mark Fisher
* @author Gunnar Hillert
* @author Artem Bilan
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
Expand All @@ -68,6 +72,10 @@ public class FileOutboundGatewayParserTests {
@Autowired
MessageChannel gatewayWithReplaceModeChannel;

@Autowired
@Qualifier("gatewayWithReplaceMode.handler")
MessageHandler gatewayWithReplaceModeHandler;

@Autowired
MessageChannel gatewayWithFailModeLowercaseChannel;

Expand All @@ -82,6 +90,7 @@ public void checkOrderedGateway() throws Exception {
assertEquals(Boolean.FALSE, gatewayAccessor.getPropertyValue("autoStartup"));
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
assertEquals(777, handlerAccessor.getPropertyValue("order"));
assertEquals(Boolean.TRUE, handlerAccessor.getPropertyValue("requiresReply"));
DefaultFileNameGenerator fileNameGenerator = (DefaultFileNameGenerator) handlerAccessor.getPropertyValue("fileNameGenerator");
assertNotNull(fileNameGenerator);
String expression = (String) TestUtils.getPropertyValue(fileNameGenerator, "expression");
Expand Down Expand Up @@ -264,6 +273,8 @@ public void gatewayWithAppendMode() throws Exception{
@Test
public void gatewayWithReplaceMode() throws Exception{

assertFalse(TestUtils.getPropertyValue(this.gatewayWithReplaceModeHandler, "requiresReply", Boolean.class));

final MessagingTemplate messagingTemplate = new MessagingTemplate(this.gatewayWithReplaceModeChannel);

String expectedFileContent = "String content:";
Expand Down
Expand Up @@ -435,6 +435,15 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="requires-reply" type="xsd:string" use="optional" default="true">
<xsd:annotation>
<xsd:documentation>
Specify whether this outbound gateway must return a non-null value. This value is
'true' by default, and a ReplyRequiredException will be thrown when
the underlying service returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Expand Down
Expand Up @@ -41,6 +41,7 @@
command-options="-P"
expression="payload"
order="2"
requires-reply="false"
>
<int-ftp:request-handler-advice-chain>
<bean class="org.springframework.integration.ftp.config.FtpOutboundGatewayParserTests$FooAdvice" />
Expand Down
Expand Up @@ -84,6 +84,7 @@ public void testGateway1() {

Long sendTimeout = TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout", Long.class);
assertEquals(Long.valueOf(777), sendTimeout);
assertTrue(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class));
}

@Test
Expand All @@ -101,6 +102,7 @@ public void testGateway2() {
Set<String> options = TestUtils.getPropertyValue(gateway, "options", Set.class);
assertTrue(options.contains(Option.PRESERVE_TIMESTAMP));
gateway.handleMessage(new GenericMessage<String>("foo"));
assertFalse(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class));
assertEquals(1, adviceCalled);
}

Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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
Expand All @@ -24,6 +24,7 @@
/**
* @author Dave Syer
* @author Gunnar Hillert
* @author Artem Bilan
*
* @since 2.0
*
Expand All @@ -48,8 +49,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
String updateQuery = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "update",
parserContext);

BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(JdbcOutboundGateway.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JdbcOutboundGateway.class);
if (refToDataSourceSet) {
builder.addConstructorArgReference(dataSourceRef);
}
Expand All @@ -68,6 +68,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "max-rows-per-poll");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "keys-generated");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply");

String replyChannel = element.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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
Expand Down Expand Up @@ -27,6 +27,7 @@

/**
* @author Gunnar Hillert
* @author Artem Bilan
* @since 2.1
*
*/
Expand Down Expand Up @@ -62,6 +63,7 @@ protected BeanDefinitionBuilder parseHandler(Element element, ParserContext pars

IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply");

String replyChannel = element.getAttribute("reply-channel");
if (StringUtils.hasText(replyChannel)) {
Expand Down
Expand Up @@ -502,6 +502,15 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="requires-reply" type="xsd:string" use="optional" default="true">
<xsd:annotation>
<xsd:documentation>
Specify whether this outbound gateway must return a non-null value. This value is
'true' by default, and a ReplyRequiredException will be thrown when
the underlying service returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Expand Down Expand Up @@ -967,6 +976,15 @@
<xsd:union memberTypes="xsd:boolean xsd:string" />
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="requires-reply" type="xsd:string" use="optional" default="false">
<xsd:annotation>
<xsd:documentation>
Specify whether this outbound gateway must return a non-null value. This value is
'false' by default, if it set to 'true', a ReplyRequiredException will be thrown when
the underlying service returns a null value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>

Expand Down

0 comments on commit f1fba65

Please sign in to comment.