INT-3555: Fix Header Channel Mapping
JIRA: https://jira.spring.io/browse/INT-3555 Previously, `replyChannel` and `errorChannel` headers were unconditionally dropped in `AbstractHeaderMapper`. This was changed in 4.1.0.M1 to allow these headers to be transmitted in the case that they were translated to a String by a `HeaderChannelRegistry`. However, we should still drop these headers if they reference live `MessageChannel` instances.
This commit is contained in:
committed by
Artem Bilan
parent
1c9cea162d
commit
90c6f2fa3e
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.amqp.outbound;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@@ -34,8 +35,10 @@ import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.rabbit.support.CorrelationData;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
@@ -73,6 +76,9 @@ public class OutboundEndpointTests {
|
||||
TestRabbitTemplate amqpTemplate = spy(new TestRabbitTemplate(connectionFactory));
|
||||
AmqpOutboundEndpoint endpoint = new AmqpOutboundEndpoint(amqpTemplate);
|
||||
endpoint.setExpectReply(true);
|
||||
DefaultAmqpHeaderMapper mapper = new DefaultAmqpHeaderMapper();
|
||||
mapper.setRequestHeaderNames("*");
|
||||
endpoint.setHeaderMapper(mapper);
|
||||
final AtomicReference<Message> amqpMessage =
|
||||
new AtomicReference<Message>();
|
||||
doAnswer(new Answer<Object>() {
|
||||
@@ -85,10 +91,12 @@ public class OutboundEndpointTests {
|
||||
}).when(amqpTemplate).doSendAndReceiveWithTemporary(anyString(), anyString(), any(Message.class));
|
||||
org.springframework.messaging.Message<?> message = MessageBuilder.withPayload("foo")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "bar")
|
||||
.setReplyChannel(new QueueChannel())
|
||||
.build();
|
||||
endpoint.handleMessage(message);
|
||||
assertNotNull(amqpMessage.get());
|
||||
assertEquals("bar", amqpMessage.get().getMessageProperties().getContentType());
|
||||
assertNull(amqpMessage.get().getMessageProperties().getHeaders().get(MessageHeaders.REPLY_CHANNEL));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -196,7 +197,7 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
|
||||
private void populateUserDefinedHeaders(Map<String, Object> headers, T target) {
|
||||
for (String headerName : headers.keySet()) {
|
||||
Object value = headers.get(headerName);
|
||||
if (value != null) {
|
||||
if (value != null && !isMessageChannel(headerName, value)) {
|
||||
try {
|
||||
if (!headerName.startsWith(this.standardHeaderPrefix)) {
|
||||
String key = this.createTargetPropertyName(headerName, true);
|
||||
@@ -212,6 +213,16 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMessageChannel(String headerName, Object headerValue) {
|
||||
if (headerValue instanceof MessageChannel) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cannot map a MessageChannel instance in header " + headerName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map headers from a source instance to the {@link MessageHeaders} of
|
||||
* a {@link org.springframework.messaging.Message}.
|
||||
@@ -245,11 +256,8 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
|
||||
}
|
||||
|
||||
private boolean shouldMapHeader(String headerName, HeaderMatcher headerMatcher) {
|
||||
if (!StringUtils.hasText(headerName)
|
||||
|| getTransientHeaderNames().contains(headerName)) {
|
||||
return false;
|
||||
}
|
||||
return headerMatcher.matchHeader(headerName);
|
||||
return !(!StringUtils.hasText(headerName) || getTransientHeaderNames().contains(headerName))
|
||||
&& headerMatcher.matchHeader(headerName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
Reference in New Issue
Block a user