INT-3235 Make GatewayMethodMetadata Public

JIRA: https://jira.springsource.org/browse/INT-3235

Unable to programmatically wire header expressions or method-specific
properties into a GatewayProxyFactoryBean.

The GPFB has public methods that take arguments of
this type.

Make the class public instead of package-protected.

Add a test case.
This commit is contained in:
Gary Russell
2013-12-13 13:42:26 -05:00
committed by Artem Bilan
parent ced1a05df2
commit ef756bfd6d
3 changed files with 42 additions and 7 deletions

View File

@@ -27,6 +27,9 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.gateway.GatewayMethodMetadata;
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -105,7 +108,7 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
if (hasDefaultHeaders || hasDefaultPayloadExpression) {
BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.gateway.GatewayMethodMetadata");
GatewayMethodMetadata.class);
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
IntegrationNamespaceUtils.setValueIfAttributeDefined(methodMetadataBuilder, element,
"default-payload-expression", "payloadExpression");
@@ -120,7 +123,7 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
for (Element methodElement : elements) {
String methodName = methodElement.getAttribute("name");
BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.gateway.GatewayMethodMetadata");
GatewayMethodMetadata.class);
methodMetadataBuilder.addPropertyValue("requestChannelName", methodElement.getAttribute("request-channel"));
methodMetadataBuilder.addPropertyValue("replyChannelName", methodElement.getAttribute("reply-channel"));
methodMetadataBuilder.addPropertyValue("requestTimeout", methodElement.getAttribute("request-timeout"));
@@ -151,11 +154,11 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
}
RootBeanDefinition expressionDef = null;
if (hasValue) {
expressionDef = new RootBeanDefinition("org.springframework.expression.common.LiteralExpression");
expressionDef = new RootBeanDefinition(LiteralExpression.class);
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(headerValue);
}
else if (hasExpression) {
expressionDef = new RootBeanDefinition("org.springframework.integration.config.ExpressionFactoryBean");
expressionDef = new RootBeanDefinition(ExpressionFactoryBean.class);
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(headerExpression);
}
if (expressionDef != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.
@@ -27,11 +27,12 @@ import org.springframework.expression.Expression;
* <p>
* The sub-element of a &lt;gateway&gt; element would look like this:
* &lt;method name="echo" request-channel="inputA" reply-timeout="2" request-timeout="200"/&gt;
*
*
* @author Oleg Zhurakousky
* @author Gary Russell
* @since 2.0
*/
class GatewayMethodMetadata {
public class GatewayMethodMetadata {
private volatile String payloadExpression;

View File

@@ -16,11 +16,14 @@
package org.springframework.integration.gateway;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -37,6 +40,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.DirectChannel;
@@ -77,6 +82,7 @@ public class GatewayProxyFactoryBeanTests {
startResponder(requestChannel);
GenericConversionService cs = new DefaultConversionService();
Converter<String, byte[]> stringToByteConverter = new Converter<String, byte[]>() {
@Override
public byte[] convert(String source) {
return source.getBytes();
}
@@ -134,6 +140,7 @@ public class GatewayProxyFactoryBeanTests {
public void testRequestReplyWithTypeConversion() throws Exception {
final QueueChannel requestChannel = new QueueChannel();
new Thread(new Runnable() {
@Override
public void run() {
Message<?> input = requestChannel.receive();
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "456");
@@ -184,6 +191,7 @@ public class GatewayProxyFactoryBeanTests {
for (int i = 0; i < numRequests; i++) {
final int count = i;
executor.execute(new Runnable() {
@Override
public void run() {
// add some randomness to the ordering of requests
try {
@@ -240,6 +248,7 @@ public class GatewayProxyFactoryBeanTests {
public void testMessageAsReturnValue() throws Exception {
final QueueChannel requestChannel = new QueueChannel();
new Thread(new Runnable() {
@Override
public void run() {
Message<?> input = requestChannel.receive();
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "bar");
@@ -291,6 +300,7 @@ public class GatewayProxyFactoryBeanTests {
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
DirectChannel channel = new DirectChannel();
EventDrivenConsumer consumer = new EventDrivenConsumer(channel, new MessageHandler() {
@Override
public void handleMessage(Message<?> message) {
Method method = ReflectionUtils.findMethod(
GatewayProxyFactoryBeanTests.class, "throwTestException");
@@ -310,6 +320,7 @@ public class GatewayProxyFactoryBeanTests {
private static void startResponder(final PollableChannel requestChannel) {
new Thread(new Runnable() {
@Override
public void run() {
Message<?> input = requestChannel.receive();
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "bar");
@@ -318,6 +329,26 @@ public class GatewayProxyFactoryBeanTests {
}).start();
}
@Test
public void testProgrammaticWiring() throws Exception {
GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean();
gpfb.setBeanFactory(mock(BeanFactory.class));
gpfb.setServiceInterface(TestEchoService.class);
QueueChannel drc = new QueueChannel();
gpfb.setDefaultRequestChannel(drc);
gpfb.setDefaultReplyTimeout(0);
GatewayMethodMetadata meta = new GatewayMethodMetadata();
meta.setHeaderExpressions(Collections. <String, Expression> singletonMap("foo", new LiteralExpression("bar")));
gpfb.setGlobalMethodMetadata(meta);
gpfb.afterPropertiesSet();
((TestEchoService) gpfb.getObject()).echo("foo");
Message<?> message = drc.receive(0);
assertNotNull(message);
String bar = (String) message.getHeaders().get("foo");
assertNotNull(bar);
assertThat(bar, equalTo("bar"));
}
// @Test
// public void testHistory() throws Exception {
// GenericApplicationContext context = new GenericApplicationContext();