Skip to content

Commit 4e15772

Browse files
artembilangaryrussell
authored andcommitted
INT-4448, INT-4449: Fix Gateway for no-arg method (#2420)
* INT-4448, INT-4449: Fix Gateway for no-arg method JIRA: https://jira.spring.io/browse/INT-4448 JIRA: https://jira.spring.io/browse/INT-4449 When we are not interested in the `payload` to send, we use a gateway method without any args, but in this case for send operation (or send-and-receive) we should specify a default `payloadExpression` The `MessagingGatewayRegistrar` fails with `NPE` if we don't have a any global headers and have `defaultPayloadExpression` Also in this case the `GatewayProxyFactoryBean` fails to send and fallbacks to receive with the meaning "no args, not payloadExpression" * Fix `MessagingGatewayRegistrar` to check `hasDefaultHeaders` before processing them * Fix `GatewayProxyFactoryBean` to consult `this.globalMethodMetadata` if there is no `payloadExpression` for the method specific metadata **Cherry-pick to 5.0.x and 4.3.x** * Remove `oracle-java8-installer` since it looks like the resource is not available anymore: ``` Location: http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.tar.gz?AuthParam=1523990114_ee8c82cbe67bc87d192cb79d3b902d2f [following] --2018-04-17 18:33:14-- http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.tar.gz?AuthParam=1523990114_ee8c82cbe67bc87d192cb79d3b902d2f Connecting to download.oracle.com (download.oracle.com)|23.53.120.105|:80... connected. HTTP request sent, awaiting response... 404 Not Found 2018-04-17 18:35:15 ERROR 404: Not Found. ```
1 parent 82e4679 commit 4e15772

File tree

5 files changed

+65
-25
lines changed

5 files changed

+65
-25
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ addons:
1111
- mongodb-3.0-precise
1212
packages:
1313
- mongodb-org-server
14-
- oracle-java8-installer
1514
before_cache:
1615
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
1716
cache:

spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2017 the original author or authors.
2+
* Copyright 2014-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -100,28 +100,33 @@ public BeanDefinitionHolder parse(Map<String, Object> gatewayAttributes) {
100100
if (hasDefaultHeaders || hasDefaultPayloadExpression) {
101101
BeanDefinitionBuilder methodMetadataBuilder =
102102
BeanDefinitionBuilder.genericBeanDefinition(GatewayMethodMetadata.class);
103+
103104
if (hasDefaultPayloadExpression) {
104105
methodMetadataBuilder.addPropertyValue("payloadExpression", defaultPayloadExpression);
105106
}
106-
Map<String, Object> headerExpressions = new ManagedMap<String, Object>();
107-
for (Map<String, Object> header : defaultHeaders) {
108-
String headerValue = (String) header.get("value");
109-
String headerExpression = (String) header.get("expression");
110-
boolean hasValue = StringUtils.hasText(headerValue);
111-
112-
if (hasValue == StringUtils.hasText(headerExpression)) {
113-
throw new BeanDefinitionStoreException("exactly one of 'value' or 'expression' " +
114-
"is required on a gateway's header.");
115-
}
116107

117-
BeanDefinition expressionDef =
118-
new RootBeanDefinition(hasValue ? LiteralExpression.class : ExpressionFactoryBean.class);
119-
expressionDef.getConstructorArgumentValues()
120-
.addGenericArgumentValue(hasValue ? headerValue : headerExpression);
108+
if (hasDefaultHeaders) {
109+
Map<String, Object> headerExpressions = new ManagedMap<String, Object>();
110+
for (Map<String, Object> header : defaultHeaders) {
111+
String headerValue = (String) header.get("value");
112+
String headerExpression = (String) header.get("expression");
113+
boolean hasValue = StringUtils.hasText(headerValue);
114+
115+
if (hasValue == StringUtils.hasText(headerExpression)) {
116+
throw new BeanDefinitionStoreException("exactly one of 'value' or 'expression' " +
117+
"is required on a gateway's header.");
118+
}
121119

122-
headerExpressions.put((String) header.get("name"), expressionDef);
120+
BeanDefinition expressionDef =
121+
new RootBeanDefinition(hasValue ? LiteralExpression.class : ExpressionFactoryBean.class);
122+
expressionDef.getConstructorArgumentValues()
123+
.addGenericArgumentValue(hasValue ? headerValue : headerExpression);
124+
125+
headerExpressions.put((String) header.get("name"), expressionDef);
126+
}
127+
methodMetadataBuilder.addPropertyValue("headerExpressions", headerExpressions);
123128
}
124-
methodMetadataBuilder.addPropertyValue("headerExpressions", headerExpressions);
129+
125130
gatewayProxyBuilder.addPropertyValue("globalMethodMetadata", methodMetadataBuilder.getBeanDefinition());
126131
}
127132

spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -487,10 +487,15 @@ private Object invokeGatewayMethod(MethodInvocation invocation, boolean runningO
487487
int paramCount = method.getParameterTypes().length;
488488
Object response = null;
489489
boolean hasPayloadExpression = method.isAnnotationPresent(Payload.class);
490-
if (!hasPayloadExpression && this.methodMetadataMap != null) {
490+
if (!hasPayloadExpression) {
491491
// check for the method metadata next
492-
GatewayMethodMetadata metadata = this.methodMetadataMap.get(method.getName());
493-
hasPayloadExpression = (metadata != null) && StringUtils.hasText(metadata.getPayloadExpression());
492+
if (this.methodMetadataMap != null) {
493+
GatewayMethodMetadata metadata = this.methodMetadataMap.get(method.getName());
494+
hasPayloadExpression = (metadata != null) && StringUtils.hasText(metadata.getPayloadExpression());
495+
}
496+
else if (this.globalMethodMetadata != null) {
497+
hasPayloadExpression = StringUtils.hasText(this.globalMethodMetadata.getPayloadExpression());
498+
}
494499
}
495500
if (paramCount == 0 && !hasPayloadExpression) {
496501
Long receiveTimeout = null;

spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests-context.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</int:channel>
1111

1212
<int:gateway id="sampleGateway"
13-
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Bar"
13+
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests$Bar"
1414
default-request-channel="requestChannelBaz"
1515
error-channel="errorChannel">
1616
<int:default-header name="name" expression="#gatewayMethod.name"/>
@@ -34,9 +34,14 @@
3434
<int:channel id="requestChannelBaz"/>
3535

3636
<int:gateway id="customMappedGateway"
37-
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Baz"
37+
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests$Baz"
3838
default-request-channel="requestChannelBaz" mapper="mapper"/>
3939

4040
<bean id="mapper" class="org.springframework.integration.gateway.GatewayInterfaceTests$BazMapper"/>
4141

42+
<int:gateway id="sampleGateway2"
43+
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests$NoArgumentsGateway"
44+
default-request-channel="requestChannelBar"
45+
default-payload-expression="'foo'"/>
46+
4247
</beans>

spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -75,6 +75,7 @@
7575
import org.springframework.integration.config.EnableIntegration;
7676
import org.springframework.integration.context.IntegrationContextUtils;
7777
import org.springframework.integration.context.IntegrationProperties;
78+
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
7879
import org.springframework.integration.handler.BridgeHandler;
7980
import org.springframework.integration.support.MessageBuilder;
8081
import org.springframework.integration.test.util.TestUtils;
@@ -487,6 +488,26 @@ public void testIgnoredHeader() {
487488
((SubscribableChannel) this.errorChannel).unsubscribe(messageHandler);
488489
}
489490

491+
@Test
492+
public void testGatewayWithNoArgsMethod() {
493+
ConfigurableApplicationContext ac =
494+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
495+
496+
DirectChannel channel = ac.getBean("requestChannelBar", DirectChannel.class);
497+
channel.subscribe(new AbstractReplyProducingMessageHandler() {
498+
499+
@Override
500+
protected Object handleRequestMessage(Message<?> requestMessage) {
501+
assertEquals("foo", requestMessage.getPayload());
502+
return "FOO";
503+
}
504+
505+
});
506+
507+
NoArgumentsGateway noArgumentsGateway = ac.getBean(NoArgumentsGateway.class);
508+
assertEquals("FOO", noArgumentsGateway.pullData());
509+
ac.close();
510+
}
490511

491512
public interface Foo {
492513

@@ -520,6 +541,11 @@ public interface Baz {
520541
void baz(String payload);
521542
}
522543

544+
public interface NoArgumentsGateway {
545+
546+
String pullData();
547+
}
548+
523549
public static class BazMapper implements MethodArgsMessageMapper {
524550

525551
@Override

0 commit comments

Comments
 (0)