Make use of enhanced MessageHeaderAccessor support

Mutate rather than re-create headers when decoding STOMP messages
before a message is sent on a message channel.

Use MessageBuilder.createMessage to ensure the fully prepared
MessageHeaders is used directly MessageHeaderAccessor instance.

Issue: SPR-11468
This commit is contained in:
Rossen Stoyanchev
2014-04-10 23:57:45 -04:00
parent 4867546aec
commit ae942ffdb8
22 changed files with 322 additions and 236 deletions

View File

@@ -112,10 +112,12 @@ public class MessageConverterTests {
public void toMessageHeadersCopied() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("foo", "bar");
MessageHeaders headers = new MessageHeaders(map );
MessageHeaders headers = new MessageHeaders(map);
Message<?> message = this.converter.toMessage("ABC", headers);
assertEquals("bar", message.getHeaders().get("foo"));
assertNotNull(message.getHeaders().getId());
assertNotNull(message.getHeaders().getTimestamp());
}
@Test

View File

@@ -31,7 +31,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.converter.*;
import org.springframework.messaging.handler.annotation.MessageMapping;

View File

@@ -38,6 +38,7 @@ import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.StubMessageChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.ExecutorSubscribableChannel;
@@ -168,7 +169,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
public void messageDeliverExceptionIfSystemSessionForwardFails() throws Exception {
stopActiveMqBrokerAndAwait();
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SEND);
this.relay.handleMessage(MessageBuilder.withPayload("test".getBytes()).setHeaders(headers).build());
this.relay.handleMessage(MessageBuilder.createMessage("test".getBytes(), headers.getMessageHeaders()));
}
@Test
@@ -244,7 +245,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.DISCONNECT);
headers.setSessionId("sess1");
this.relay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
this.relay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
Thread.sleep(2000);
@@ -394,7 +395,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
headers.setSessionId(sessionId);
headers.setAcceptVersion("1.1,1.2");
headers.setHeartbeat(0, 0);
Message<?> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build();
Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders());
MessageExchangeBuilder builder = new MessageExchangeBuilder(message);
builder.expected.add(new StompConnectedFrameMessageMatcher(sessionId));
@@ -405,7 +406,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
headers.setSessionId(sessionId);
headers.setAcceptVersion("1.1,1.2");
Message<?> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build();
Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders());
MessageExchangeBuilder builder = new MessageExchangeBuilder(message);
return builder.andExpectError();
}
@@ -418,7 +419,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
headers.setSubscriptionId(subscriptionId);
headers.setDestination(destination);
headers.setReceipt(receiptId);
Message<?> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build();
Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders());
MessageExchangeBuilder builder = new MessageExchangeBuilder(message);
builder.expected.add(new StompReceiptFrameMessageMatcher(sessionId, receiptId));
@@ -426,14 +427,14 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
}
public static MessageExchangeBuilder send(String destination, String payload) {
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SEND);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headers.setDestination(destination);
Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).setHeaders(headers).build();
Message<?> message = MessageBuilder.createMessage(payload.getBytes(UTF_8), headers.getMessageHeaders());
return new MessageExchangeBuilder(message);
}
public MessageExchangeBuilder andExpectMessage(String sessionId, String subscriptionId) {
Assert.isTrue(StompCommand.SEND.equals(headers.getCommand()), "MESSAGE can only be expected after SEND");
Assert.isTrue(SimpMessageType.MESSAGE.equals(headers.getMessageType()));
String destination = this.headers.getDestination();
Object payload = this.message.getPayload();
this.expected.add(new StompMessageFrameMessageMatcher(sessionId, subscriptionId, destination, payload));

View File

@@ -27,6 +27,7 @@ import org.springframework.messaging.StubMessageChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.messaging.tcp.ReconnectStrategy;
import org.springframework.messaging.tcp.TcpConnection;
import org.springframework.messaging.tcp.TcpConnectionHandler;
@@ -77,17 +78,21 @@ public class StompBrokerRelayMessageHandlerTests {
String sessionId = "sess1";
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
headers.setSessionId(sessionId);
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
assertEquals(2, sent.size());
StompHeaderAccessor headers1 = StompHeaderAccessor.wrap(sent.get(0));
assertEquals(virtualHost, headers1.getHost());
assertNotNull("The prepared message does not have an accessor",
MessageHeaderAccessor.getAccessor(sent.get(0), MessageHeaderAccessor.class));
StompHeaderAccessor headers2 = StompHeaderAccessor.wrap(sent.get(1));
assertEquals(sessionId, headers2.getSessionId());
assertEquals(virtualHost, headers2.getHost());
assertNotNull("The prepared message does not have an accessor",
MessageHeaderAccessor.getAccessor(sent.get(1), MessageHeaderAccessor.class));
}
@Test
@@ -104,7 +109,7 @@ public class StompBrokerRelayMessageHandlerTests {
String sessionId = "sess1";
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
headers.setSessionId(sessionId);
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
assertEquals(2, sent.size());
@@ -126,11 +131,13 @@ public class StompBrokerRelayMessageHandlerTests {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headers.setSessionId("sess1");
headers.setDestination("/user/daisy/foo");
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
assertEquals(1, sent.size());
assertEquals(StompCommand.CONNECT, StompHeaderAccessor.wrap(sent.get(0)).getCommand());
assertNotNull("The prepared message does not have an accessor",
MessageHeaderAccessor.getAccessor(sent.get(0), MessageHeaderAccessor.class));
}

View File

@@ -66,8 +66,7 @@ public class UserDestinationMessageHandlerTests {
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
Mockito.verify(this.brokerChannel).send(captor.capture());
assertEquals("/queue/foo-user123",
captor.getValue().getHeaders().get(SimpMessageHeaderAccessor.DESTINATION_HEADER));
assertEquals("/queue/foo-user123", SimpMessageHeaderAccessor.getDestination(captor.getValue().getHeaders()));
}
@Test
@@ -79,8 +78,7 @@ public class UserDestinationMessageHandlerTests {
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
Mockito.verify(this.brokerChannel).send(captor.capture());
assertEquals("/queue/foo-user123",
captor.getValue().getHeaders().get(SimpMessageHeaderAccessor.DESTINATION_HEADER));
assertEquals("/queue/foo-user123", SimpMessageHeaderAccessor.getDestination(captor.getValue().getHeaders()));
}
@Test
@@ -93,10 +91,8 @@ public class UserDestinationMessageHandlerTests {
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
Mockito.verify(this.brokerChannel).send(captor.capture());
assertEquals("/queue/foo-user123",
captor.getValue().getHeaders().get(SimpMessageHeaderAccessor.DESTINATION_HEADER));
assertEquals("/user/queue/foo",
captor.getValue().getHeaders().get(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION));
assertEquals("/queue/foo-user123", SimpMessageHeaderAccessor.getDestination(captor.getValue().getHeaders()));
assertEquals("/user/queue/foo", captor.getValue().getHeaders().get(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION));
}