INT-3554: Add Expression Setters

JIRA: https://jira.spring.io/browse/INT-3554

**Cherry-pick to 4.0.x**

Polishing
This commit is contained in:
Artem Bilan
2014-11-07 12:37:49 +02:00
committed by Gary Russell
parent 90c6f2fa3e
commit cb50b1565c
11 changed files with 127 additions and 27 deletions

View File

@@ -70,9 +70,9 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
private volatile String routingKey;
private volatile String exchangeNameExpression;
private volatile Expression exchangeNameExpression;
private volatile String routingKeyExpression;
private volatile Expression routingKeyExpression;
private volatile ExpressionEvaluatingMessageProcessor<String> routingKeyGenerator;
@@ -80,7 +80,7 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
private volatile AmqpHeaderMapper headerMapper = new DefaultAmqpHeaderMapper();
private volatile String confirmCorrelationExpression;
private volatile Expression confirmCorrelationExpression;
private volatile ExpressionEvaluatingMessageProcessor<Object> correlationDataGenerator;
@@ -109,7 +109,22 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
this.exchangeName = exchangeName;
}
/**
* @deprecated in favor of {@link #setExpressionExchangeName}. Will be changed in a future release
* to use an {@link Expression} parameter.
* @param exchangeNameExpression the expression to set
*/
@Deprecated
public void setExchangeNameExpression(String exchangeNameExpression) {
Assert.hasText(exchangeNameExpression);
this.exchangeNameExpression = expressionParser.parseExpression(exchangeNameExpression);
}
/**
* Temporary, will be changed to {@link #setExchangeNameExpression} in a future release.
* @param exchangeNameExpression the expression to set
*/
public void setExpressionExchangeName(Expression exchangeNameExpression) {
this.exchangeNameExpression = exchangeNameExpression;
}
@@ -118,7 +133,22 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
this.routingKey = routingKey;
}
/**
* @deprecated in favor of {@link #setExpressionRoutingKey}. Will be changed in a future release
* to use an {@link Expression} parameter.
* @param routingKeyExpression the expression to set.
*/
@Deprecated
public void setRoutingKeyExpression(String routingKeyExpression) {
Assert.hasText(routingKeyExpression);
setExpressionRoutingKey(expressionParser.parseExpression(routingKeyExpression));
}
/**
* Temporary, will be changed to {@code setRoutingKeyExpression} in a future release.
* @param routingKeyExpression the expression to set
*/
public void setExpressionRoutingKey(Expression routingKeyExpression) {
this.routingKeyExpression = routingKeyExpression;
}
@@ -126,7 +156,18 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
this.expectReply = expectReply;
}
/**
* @deprecated in favor of {@link #setExpressionConfirmCorrelation}. Will be changed in a future release
* to use {@link Expression} parameter.
* @param confirmCorrelationExpression the expression to set.
*/
@Deprecated
public void setConfirmCorrelationExpression(String confirmCorrelationExpression) {
Assert.hasText(confirmCorrelationExpression);
setExpressionConfirmCorrelation(expressionParser.parseExpression(confirmCorrelationExpression));
}
public void setExpressionConfirmCorrelation(Expression confirmCorrelationExpression) {
this.confirmCorrelationExpression = confirmCorrelationExpression;
}
@@ -169,25 +210,25 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler
Assert.state(this.confirmCorrelationExpression == null || !this.expectReply,
"Confirm correlation expression does not apply to a gateway");
BeanFactory beanFactory = this.getBeanFactory();
if (exchangeNameExpression != null) {
Expression expression = expressionParser.parseExpression(this.exchangeNameExpression);
this.exchangeNameGenerator = new ExpressionEvaluatingMessageProcessor<String>(expression, String.class);
if (this.exchangeNameExpression != null) {
this.exchangeNameGenerator = new ExpressionEvaluatingMessageProcessor<String>(this.exchangeNameExpression,
String.class);
if (beanFactory != null) {
this.exchangeNameGenerator.setBeanFactory(beanFactory);
}
}
Assert.state(routingKeyExpression == null || routingKey == null,
"Either a routingKey or a routingKeyExpression can be provided, but not both");
if (routingKeyExpression != null) {
Expression expression = expressionParser.parseExpression(this.routingKeyExpression);
this.routingKeyGenerator = new ExpressionEvaluatingMessageProcessor<String>(expression, String.class);
if (this.routingKeyExpression != null) {
this.routingKeyGenerator = new ExpressionEvaluatingMessageProcessor<String>(this.routingKeyExpression,
String.class);
if (beanFactory != null) {
this.routingKeyGenerator.setBeanFactory(beanFactory);
}
}
if (this.confirmCorrelationExpression != null) {
Expression expression = expressionParser.parseExpression(this.confirmCorrelationExpression);
this.correlationDataGenerator = new ExpressionEvaluatingMessageProcessor<Object>(expression, Object.class);
this.correlationDataGenerator =
new ExpressionEvaluatingMessageProcessor<Object>(this.confirmCorrelationExpression, Object.class);
Assert.isInstanceOf(RabbitTemplate.class, this.amqpTemplate,
"RabbitTemplate implementation is required for publisher confirms");
((RabbitTemplate) this.amqpTemplate).setConfirmCallback(this);

View File

@@ -53,7 +53,8 @@ import org.springframework.util.ClassUtils;
*/
public class OutboundGatewayTests {
private final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
private final ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
@Test
public void testVanillaConfiguration() throws Exception {
@@ -65,11 +66,12 @@ public class OutboundGatewayTests {
public void testExpressionBasedConfiguration() throws Exception {
assertTrue(context.getBeanFactory().containsBeanDefinition("expression"));
Object target = context.getBean("expression");
assertNotNull(ReflectionTestUtils.getField(ReflectionTestUtils.getField(target, "handler"), "routingKeyGenerator"));
assertNotNull(ReflectionTestUtils.getField(ReflectionTestUtils.getField(target, "handler"),
"routingKeyGenerator"));
}
@SuppressWarnings("unchecked")
@Test
@SuppressWarnings({"unchecked", "deprecation"})
public void testExpressionsBeanResolver() throws Exception {
ApplicationContext context = mock(ApplicationContext.class);
doAnswer(new Answer<Object>() {
@@ -82,11 +84,13 @@ public class OutboundGatewayTests {
when(context.getBean(ClassUtils.forName("org.springframework.integration.config.SpelPropertyAccessorRegistrar",
context.getClassLoader())))
.thenThrow(NoSuchBeanDefinitionException.class);
IntegrationEvaluationContextFactoryBean integrationEvaluationContextFactoryBean = new IntegrationEvaluationContextFactoryBean();
IntegrationEvaluationContextFactoryBean integrationEvaluationContextFactoryBean =
new IntegrationEvaluationContextFactoryBean();
integrationEvaluationContextFactoryBean.setApplicationContext(context);
integrationEvaluationContextFactoryBean.afterPropertiesSet();
StandardEvaluationContext evalContext = integrationEvaluationContextFactoryBean.getObject();
when(context.getBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, StandardEvaluationContext.class))
when(context.getBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
StandardEvaluationContext.class))
.thenReturn(evalContext);
RabbitTemplate template = mock(RabbitTemplate.class);
AmqpOutboundEndpoint endpoint = new AmqpOutboundEndpoint(template);

View File

@@ -17,6 +17,7 @@ import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.expression.IntegrationEvaluationContextAware;
import org.springframework.util.Assert;
/**
* A {@link MessageProducerSupport} sub-class that provides {@linkplain #payloadExpression}
@@ -30,19 +31,29 @@ import org.springframework.integration.expression.IntegrationEvaluationContextAw
*/
public abstract class ExpressionMessageProducerSupport extends MessageProducerSupport implements IntegrationEvaluationContextAware {
private final SpelExpressionParser parser = new SpelExpressionParser();
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
private volatile Expression payloadExpression;
private volatile EvaluationContext evaluationContext;
/**
* @deprecated in favor of {@link #setExpressionPayload}. Will be changed in a future release
* to use an {@link Expression} parameter.
* @param payloadExpression the expression to set.
*/
@Deprecated
public void setPayloadExpression(String payloadExpression) {
if (payloadExpression == null) {
this.payloadExpression = null;
}
else {
this.payloadExpression = this.parser.parseExpression(payloadExpression);
}
Assert.hasText(payloadExpression);
setExpressionPayload(PARSER.parseExpression(payloadExpression));
}
/**
* Temporary, will be changed to {@link #setPayloadExpression} in a future release.
* @param payloadExpression the expression to set.
*/
public void setExpressionPayload(Expression payloadExpression) {
this.payloadExpression = payloadExpression;
}
@Override

View File

@@ -67,11 +67,19 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan
this.onSuccessExpression = new SpelExpressionParser().parseExpression(onSuccessExpression);
}
public void setOnSuccessExpression(Expression onSuccessExpression) {
this.onSuccessExpression = onSuccessExpression;
}
public void setOnFailureExpression(String onFailureExpression) {
Assert.notNull(onFailureExpression, "'onFailureExpression' must not be null");
this.onFailureExpression = new SpelExpressionParser().parseExpression(onFailureExpression);
}
public void setOnFailureExpression(Expression onFailureExpression) {
this.onFailureExpression = onFailureExpression;
}
public void setSuccessChannel(MessageChannel successChannel) {
Assert.notNull(successChannel,"'successChannel' must not be null");
this.successChannel = successChannel;

View File

@@ -35,7 +35,7 @@ import org.springframework.util.Assert;
/**
* An inbound Channel Adapter that implements {@link ApplicationListener} and
* passes Spring {@link ApplicationEvent ApplicationEvents} within messages.
* If a {@link #setPayloadExpression(String) payloadExpression} is provided, it will be evaluated against
* If a {@link #setPayloadExpression payloadExpression} is provided, it will be evaluated against
* the ApplicationEvent instance to create the Message payload. Otherwise, the event itself will be the payload.
*
* @author Mark Fisher

View File

@@ -134,6 +134,7 @@ public class ApplicationEventListeningMessageProducerTests {
}
@Test
@SuppressWarnings("deprecation")
public void payloadExpressionEvaluatedAgainstApplicationEvent() {
QueueChannel channel = new QueueChannel();
ApplicationEventListeningMessageProducer adapter = new ApplicationEventListeningMessageProducer();

View File

@@ -311,10 +311,24 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
this.mputFilter = filter;
}
/**
* @deprecated in favor of {@link #setExpressionRename}. Will be changed in a future release
* to use an {@link Expression} parameter.
* @param expression the expression to set.
*/
@Deprecated
public void setRenameExpression(String expression) {
Assert.notNull(expression, "'expression' cannot be null");
this.renameProcessor = new ExpressionEvaluatingMessageProcessor<String>(
new SpelExpressionParser().parseExpression(expression));
setExpressionRename(new SpelExpressionParser().parseExpression(expression));
}
/**
* Temporary, will be changed to {@link #setRenameExpression} in a future release.
* @param expression the expression to set.
*/
public void setExpressionRename(Expression expression) {
Assert.notNull(expression, "'expression' cannot be null");
this.renameProcessor = new ExpressionEvaluatingMessageProcessor<String>(expression);
}
public void setLocalFilenameGeneratorExpression(Expression localFilenameGeneratorExpression) {

View File

@@ -270,6 +270,7 @@ public class RemoteFileOutboundGatewayTests {
}
@Test
@SuppressWarnings("deprecation")
public void testMoveWithExpression() throws Exception {
SessionFactory sessionFactory = mock(SessionFactory.class);
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway
@@ -295,6 +296,7 @@ public class RemoteFileOutboundGatewayTests {
}
@Test
@SuppressWarnings("deprecation")
public void testMoveWithMkDirs() throws Exception {
SessionFactory sessionFactory = mock(SessionFactory.class);
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway

View File

@@ -40,6 +40,7 @@ import com.gemstone.gemfire.cache.Region;
public class CacheListeningMessageProducerTests {
@Test
@SuppressWarnings("deprecation")
public void receiveNewValuePayloadForCreateEvent() throws Exception {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
Cache cache = cacheFactoryBean.getObject();
@@ -66,6 +67,7 @@ public class CacheListeningMessageProducerTests {
}
@Test
@SuppressWarnings("deprecation")
public void receiveNewValuePayloadForUpdateEvent() throws Exception {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
Cache cache = cacheFactoryBean.getObject();
@@ -96,6 +98,7 @@ public class CacheListeningMessageProducerTests {
}
@Test
@SuppressWarnings("deprecation")
public void receiveOldValuePayloadForDestroyEvent() throws Exception {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
Cache cache = cacheFactoryBean.getObject();
@@ -125,6 +128,7 @@ public class CacheListeningMessageProducerTests {
}
@Test
@SuppressWarnings("deprecation")
public void receiveOldValuePayloadForInvalidateEvent() throws Exception {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
Cache cache = cacheFactoryBean.getObject();

View File

@@ -85,6 +85,7 @@ public class ContinuousQueryMessageProducerTests {
}
@Test
@SuppressWarnings("deprecation")
public void testPayloadExpression() {
CqEvent cqEvent = event(Operation.CREATE, "hello");
cqMessageProducer.setPayloadExpression("newValue.toUpperCase() + ', WORLD'");

View File

@@ -78,9 +78,23 @@ public class RedisOutboundGateway extends AbstractReplyProducingMessageHandler
this.argumentsSerializer = (RedisSerializer<Object>) serializer;
}
/**
* @deprecated in favor of {@link #setExpressionCommand}. Will be changed in a future release
* to use an {@link Expression} parameter.
* @param commandExpression the expression to set.
*/
@Deprecated
public void setCommandExpression(String commandExpression) {
Assert.hasText(commandExpression, "'commandExpression' must not be an empty string");
this.commandExpression = PARSER.parseExpression(commandExpression);
setExpressionCommand(PARSER.parseExpression(commandExpression));
}
/**
* Temporary, will be changed to {@link #setCommandExpression} in a future release.
* @param commandExpression the expression to set.
*/
public void setExpressionCommand(Expression commandExpression) {
this.commandExpression = commandExpression;
}
public void setArgumentsStrategy(ArgumentsStrategy argumentsStrategy) {